home *** CD-ROM | disk | FTP | other *** search
/ BBS Toolkit / BBS Toolkit.iso / rbbs_pc / tabs.zip / RBBSSUB2.BAS < prev    next >
BASIC Source File  |  1990-05-08  |  140KB  |  4,060 lines

  1. ' $linesize:132
  2. ' $title: 'RBBSSUB2.BAS CPC17.3, Copyright 1986 - 90 by D. Thomas Mack'
  3. '  Copyright 1990 by D. Thomas Mack, all rights reserved.
  4. '  Name ...............: RBBSSUB2.BAS
  5. '  First Released .....: February 11, 1990
  6. '  Subsequent Releases.:
  7. '  Copyright ..........: 1986 - 1990
  8. '  Purpose.............: The Remote Bulletin Board System for the IBM PC,
  9. '     RBBS-PC.BAS utilizes a lot of common subroutines.  Those that do not
  10. '     require error trapping are incorporated within RBBSSUB 2-5 as
  11. '     separately callable subroutines in order to free up as much
  12. '     code as possible within the 64WasK code segment used by RBBS-PC.BAS.
  13. '  Parameters..........: Most parameters are passed via a COMMON statement.
  14. '
  15. ' Subroutine  Line               Function of Subroutine
  16. '   Name     Number
  17. '  Macro          1320  Check/execute macro
  18. '  AnswerIt        200  Answer the telephone when it rings
  19. '  ASCIICodes      129  Allow a CONFIG string to have any ASCII value
  20. '  BadChar         455  Check user name for invalid characters
  21. '  BadName       20235  Check for system crash attempt with bad file name
  22. '  Baud450        5507  Allow 300 baud callers to bump up to 450 baud
  23. '  CheckRatio    20096  Test upload/download ratio
  24. '  CheckMacro     1242  Checks for macro and processes
  25. '  CopyRight        97  Display RBBS-PC's copyright notice
  26. '  DEFALTU        9600  Write out the user's defaults
  27. '  DenyAccess     1386  Downgrade security so access denied
  28. '  DoorExit      10983  Set up a .BAT file to exit RBBS-PC to a "door"
  29. '  DosExit       10934  Set up a .BAT file to exit to DOS (second level)
  30. '  EditALine      2618  Edits a single line
  31. '  EditDef         120  Edit configuration parameters
  32. '  FileNameCheck 20240  Matches file name to a prefix & extension
  33. '  GetArc        20140  Handle request for verbose listing
  34. '  GetCommand      101  Get RBBS-PC's node id from command line
  35. '  GetTime        9140  Calculates callers elapsed time (hh,mm,ss)
  36. '  GoIdle           90  Release resources when waiting for keyboard input
  37. '  KillMsg        3952  Delete old or unnecessary messages
  38. '  Line25          945  Build and/or update line 25 of RBBS-PC's local screen
  39. '  LineEdit       3700  Edit a line while minimizing string space consumption
  40. '  LogError      13660  Log error message to CALLERS file
  41. '  LPrnt          1480  Subroutine to write to local display
  42. '  MLInit            8  Handle MultiLink initialization/de-initialization
  43. '  MsgProt        2055  Sets protection for a message
  44. '  MessageTo      2018  Sets who a message is to
  45. '  PageLen        5200  Change page length
  46. '  ParseIt        1637  Parses a string
  47. '  PassWrd         660  Verify user & message passwords
  48. '  PopCmdStack    1650  Get user input, 1st checking command stack
  49. '  PScrn          1483  Print to display
  50. '  QuickLPrnt     1482  Quickly writes count of blocks on file transfer
  51. '  QuickTPut      1478  Fast, but limited, "TPut" equivalent
  52. '  QuickTPut1     1478  Outputs short string following by CR LF
  53. '  RBBSExit      10992  RBBS-PC exit to transfer control to other programs
  54. '  RecoverMsg    10410  Recover a deleted message
  55. '  RemNonAlf      5100  Removes non-alpha characters from a string
  56. '  RingCaller     1636  Ring caller's bell and put message in emphasis
  57. '  SetBaud        1654  Set baud rate in the 8250 chip of the RS232 interface
  58. '  SetCrLf        1496  Set up the necessary carriage return/line feed string
  59. '  SetSection    12000  Set the proper section prompts (main, file, util, libr)
  60. '  SetThread      4554  Set up request for threading thru messages
  61. '  SkipLine       1485  Write a # of blank lines to the communications port
  62. '  SearchCmd      1238  Searches list of commands in RBBS for a request
  63. '  SecViolation   1380  Process a security violation
  64. '  SysMenu         112  Displays sysop menu/status
  65. '  SysopChat      4773  Sysop and caller chat
  66. '  TestRel         336  Tests for Reliable connect
  67. '  TGet           1498  Read a line from the communications port
  68. '  TPut           1396  Write a line to the communications port
  69. '  Trim            105  Strip leading and trailing blanks from a string
  70. '  TrimTrail       107  Strip off specified string off end of another string
  71. '  UntilRight    12878  Ask a question until user says answer is right
  72. '  UpdateU       10600  Updates the user record on loging off/exiting RBBS-PC
  73. '  VarInit         109  Initialize system variables
  74. '  ViewHelp       1330  Processes help command
  75. '  WhoCheck       2250  Checks whether a user exists in user file
  76. '  WhosOn         9801  Report status of each node - who's on
  77. '  WordInFile    10976  Find a whole word within a file/menu
  78. '
  79. '  $INCLUDE: 'RBBS-VAR.BAS'
  80. '
  81. 8 '  $SUBTITLE: 'MLInit - MultiLink initialization/deinitialization'
  82. '  $PAGE
  83. '
  84. '  NAME    -- MLInit
  85. '
  86. '  INPUTS  --  MLParm = 1             INITIALIZE AT STARTUP OR RE-
  87. '                                     CYLCE TIME
  88. '              MLParm = 2             DE-INITIALIZE ON EXITING TO
  89. '                                     A DOOR OR DOS REMOTELY
  90. '              MLParm = 3             DE-QUEUE COMMUNICATIONS PORTS
  91. '              MLParm = 4             CHECK FOR MULTILINK PRESENT
  92. '              ZDoorsTermType
  93. '              ZBaudTest!
  94. '              ZComPort$
  95. '              ZComputerType
  96. '
  97. '  OUTPUTS --  NONE
  98. '
  99. '  PURPOSE --  To test for the presence of multi-link and set
  100. '              multi link options to be compatible with RBBS-PC
  101. '
  102.       SUB MLInit (MLParm) STATIC
  103.     DEF SEG = 0
  104.     IF ZComputerType = 1 _
  105.        GOTO 10
  106.     IF NOT ZMLCom THEN _
  107.        IF ZNetworkType <> 1 THEN _
  108.           GOTO 10
  109.     ZMultiLinkPresent = PEEK(&H1FE) + 256 * PEEK(&H1FF)
  110.     IF ZMultiLinkPresent = 0 THEN _
  111.        GOTO 10
  112.     ON MLParm GOSUB 30,20,60,10
  113. 10  DEF SEG
  114.     EXIT SUB
  115. 20  IF ZDoorsTermType < 1 THEN _
  116.        RETURN
  117.     DEF SEG = ZMultiLinkPresent
  118.     GOSUB 60
  119. ' **************     MLUTIL BAUD n (where n = ZBaudTest!)  ******
  120.     WasAX = &H600
  121.     WasBX = ZBaudTest!   ' Tell ML the baud rate
  122.     GOSUB 80
  123. ' **************     MLUTIL TERM n (where n = ZDoorsTermType) ****
  124.     WasAX = &H700 + ZDoorsTermType
  125.     GOSUB 80         ' Tell ML the terminal type
  126. ' *********          MLINK /port       ***********
  127. '                    ' Tell ML the communications port
  128.     POKE (&H64 + PEEK(&H58) + 256 * PEEK(&H59) + &HC),ASC(RIGHT$(ZComPort$,1)) - 48
  129. ' ************       MLUTIL SCMON       *************
  130.     WasAX = &HB01
  131.     WasBX = 0           ' Tell ML to start monitoring the carrier
  132.     GOSUB 80
  133.     RETURN
  134. ' **************     MLUTIL CCMON       ***************
  135. 30  WasAX = &HB00       ' Turn off ML's carrier monitoring.
  136.     WasBX = 0
  137.     GOSUB 80
  138. ' **************     MLUTIL TERM 1       *************
  139.     WasAX = &H701       ' Change terminal type to ML type 1.
  140.     WasBX = 0
  141.     GOSUB 80
  142. ' *******  MLINK /port (where port = 9 if ML 3.03 or earlier  ******
  143. ' *******            port = 0 if ML 4.00 or greater           ******
  144.     DEF SEG = ZMultiLinkPresent
  145.     MultiLinkCommPort = (&H64 + PEEK(&H58) + 256 * PEEK(&H59) + &HC)
  146.     MultiLinkVersion = PEEK(&H1) + 256 * PEEK(&H2)
  147.     IF PEEK(MultiLinkCommPort) = &H1 OR _
  148.        PEEK(MultiLinkCommPort) = &H2 THEN _
  149.        IF MultiLinkVersion > 5000 THEN _
  150.           POKE (MultiLinkCommPort),&H0 _
  151.        ELSE POKE (MultiLinkCommPort),&H9
  152. ' **********         MLUTIL ENQ         **********
  153.     WasAX = &H1        ' Tell ML to conditional enque on the comm. port
  154.     GOSUB 70
  155. ' **********         MLUTIL BAUD 19200      *********
  156.     WasAX = &H600       ' Tell ML to reset the buad rate (19200 BAUD)
  157.     WasBX = 19200
  158.     GOSUB 80
  159.     RETURN
  160. ' **********         MLUTIL DEQ         *********
  161. 60 WasAX = &H100        ' Tell ML to unconditionally deque the comm. port
  162. 70 WasBX = -4
  163.    IF ZComPort$ = "COM2" THEN _
  164.       WasBX = -3
  165.    IF ZComPort$ = "COM0" THEN _
  166.       RETURN
  167. ' ******  MULTI-LINK PROGRAMMING SUPPORT INTERFACE  *******
  168. 80 CALL RBBSML(WasAX,WasBX)
  169.    RETURN
  170.    END SUB
  171. 90 '  $SUBTITLE: 'GoIdle - release control when waiting'
  172. '  $PAGE
  173. '
  174. '  NAME    -- GoIdle
  175. '
  176. '  INPUTS  -- ZMLCom
  177. '             ZNetworkType
  178. '
  179. '  OUTPUTS --  NONE
  180. '
  181. '  PURPOSE --  To relinquish control when RBBS-PC is waiting for
  182. '              input from the communications port
  183. '
  184.       SUB GoIdle STATIC
  185.    IF ZMLCom OR ZNetworkType = 1 THEN _
  186.       CALL MLInit(5) : _
  187.       EXIT SUB
  188.    CALL GiveBack
  189.    END SUB
  190. 97 '  $SUBTITLE: 'CopyRight - subroutine to display RBBS-PC copyright'
  191. '  $PAGE
  192. '
  193. '  NAME    -- CopyRight
  194. '
  195. '  INPUTS  --  NONE
  196. '
  197. '  OUTPUTS --  NONE
  198. '
  199. '  PURPOSE --  To display RBBS-PC's copyright notice on the local screen
  200. '
  201.       SUB CopyRight STATIC
  202.    ZWasA = (ZRecycleToDos OR ZDebug OR ZNodeRecIndex > 2)
  203.    IF ZWasA THEN _
  204.       EXIT SUB
  205.    WIDTH 80
  206.    REDIM ZOutTxt$(11)
  207.    ZOutTxt$(1) = "If you use RBBS-PC CPC17.3, please consider contributing to"
  208.    ZOutTxt$(2) = ""
  209.    ZOutTxt$(3) = "             Capital PC Software Exchange"
  210.    ZOutTxt$(4) = "                 Post Office Box 6128"
  211.    ZOutTxt$(5) = "            Silver Spring, Maryland  20906"
  212.    ZOutTxt$(6) = ""
  213.    ZOutTxt$(7) = "You are free to copy and share RBBS-PC CPC17.3 provided"
  214.    ZOutTxt$(08)= "  1.  This program is distributed unmodified"
  215.    ZOutTxt$(09)= "  2.  No fee or consideration is charged for RBBS-PC itself"
  216.    ZOutTxt$(10)= "  3.  This notice is not bypassed or removed."
  217.    CLS
  218.    KEY OFF
  219.    LOCATE ,,0
  220.    ZSnoop = -1
  221.    ZLocalUser = -1
  222.    CALL LPrnt(SPACE$(60) + "tm",1)
  223.    CALL LPrnt(SPACE$(16) + STRING$(15,205) + " U S E R W A R E " + STRING$(15,205),1)
  224.    CALL SkipLine(1)
  225.    CALL LPrnt(SPACE$(17) + "Capital PC User Group User-Supported Software",1)
  226.    CALL SkipLine (1)
  227.    CALL LPrnt(SPACE$(5) + CHR$(214) + STRING$(66,196) + CHR$(183),1)
  228.    FOR WasI = 1 TO 10
  229.       CALL LPrnt(SPACE$(5) + CHR$(186) + "    " + ZOutTxt$(WasI) + SPACE$(62 - LEN(ZOutTxt$(WasI))) + CHR$(186),1)
  230.    NEXT
  231.    CALL LPrnt(SPACE$(5) + CHR$(211) + STRING$(66,196) + CHR$(189),1)
  232.    CALL LPrnt(SPACE$(5) + "Copyright (c) 1983-90 Tom Mack, 39 Cranbury Drive, Trumbull, CT 06611",1)
  233.    CALL DelayTime (8)
  234.    ZSnoop = 0
  235.    END SUB
  236. 101 ' $SUBTITLE: 'GetCommand - sub to get command from command line'
  237. ' $PAGE
  238. '
  239. '  NAME    -- GetCommand
  240. '
  241. '  INPUTS  --     PARAMETER                    MEANING
  242. '             ZConfigFileName$     NAME OF RBBS-PC ".DEF" FILE TO
  243. '                                  USE AS A MODEL WHEN CREATING THE
  244. '                                  .DEF FILE NAME TO BE USED BY THIS
  245. '                                  COPY OF RBBS-PC.
  246. '
  247. '             COMMAND LINE         COMMAND LINE USED TO INVOKE
  248. '                                  RBBS-PC IN THE FORM:
  249. '
  250. '       RBBS-PC.EXE x filename DEBUG /time /baud /reliable
  251. '
  252. '   WHERE THE OPTIONAL PARAMETERS ARE:
  253. '
  254. '  x       IS THE NODE ID IN THE RANGE 1-9,0,A-Z
  255. ' filename IS THE FULLY QUALIFIED FILE NAME TO USE AS THE ".DEF" FILE
  256. ' DEBUG    IS A DEBUGGING Switch
  257. ' /time    IS THE TIME OF DAY FOR RBBS-PC TO RETURN TO THE CALLER
  258. ' /baud    IS THE BAUD RATE OF THE CALLER IF RBBS-PC IS BEING SHELLED TO BY
  259. '             ANOTHER COMMUNICATIONS PROGRAM (THE COMMUNICATIONS PORT BEING
  260. '             USED IS ASSUMED TO BE THE ONE INPUTTED VIA THE RBBS-PC CONFIG
  261. '             PROGRAM
  262. ' /reliable IS IF RELIABLE MODE WAS DETECTED BY A HOST MAILER
  263. '
  264. ' IF NO PARAMETERS ARE SUPPLIED, RBBS-PC ASSUMES THAT THE .DEF FILE NAME IS
  265. ' RBBS-PC.DEF AND THAT THE NODE IS NODE 1.
  266. '
  267. '  OUTPUTS -- ZConfigFileName$     NAME OF RBBS-PC ".DEF" FILE FOR
  268. '                                  THIS COPY OF RBBS-PC TO USE
  269. '             ZNodeRecIndex    RECORD NUMBER WITHIN THE
  270. '                                  MESSAGES FILE FOR THIS "NODE"
  271. '                                  (RANGE IS 2 TO 36)
  272. '
  273. '  PURPOSE --  To get node id from command line and determine if rbbs
  274. '              is being run as a door
  275. '
  276.       SUB GetCommand (PassedDebug,NetTime$,ZNetBaud$,ZNetReliable$) STATIC
  277.       STATIC ZDebug
  278. '
  279. '
  280. ' *  GET NODE ID FROM COMMAND LINE
  281. '
  282. '
  283.       WasPM$ = COMMAND$
  284.       CALL AllCaps(WasPM$)
  285.       IF INSTR(WasPM$,"/") = 0 THEN _
  286.          GOTO 103
  287. '
  288. '
  289. ' * PARSE THE COMMAND LINE FOR THREE POSITIONAL SWITCHES FOR NET MAIL
  290. '
  291. '
  292.       CmdLine$ = MID$(WasPM$,INSTR(WasPM$,"/"))
  293.       WasPM$ = LEFT$(WasPM$,INSTR(WasPM$,"/") - 1)
  294.       ZWasA = 0
  295.       FOR WasX = 1 TO LEN(CmdLine$)
  296.           IF MID$(CmdLine$,WasX,1) = "/" THEN _
  297.              ZWasA = ZWasA + 1 : _
  298.              ZSubDir$(ZWasA) = "" _
  299.           ELSE ZSubDir$(ZWasA) = ZSubDir$(ZWasA) + MID$(CmdLine$,WasX,1)
  300.       NEXT
  301.       NetTime$ = ZSubDir$(1)
  302.       IF ZWasA > 1 THEN _
  303.          ZNetBaud$ = ZSubDir$(2)
  304.       IF ZWasA > 2 THEN _
  305.          ZNetReliable$ = ZSubDir$(3)
  306.       CALL Trim(NetTime$)
  307.       CALL Trim(ZNetBaud$)
  308.       CALL Trim(ZNetReliable$)
  309. 103   ZWasA = INSTR(WasPM$,"DEBUG")
  310.       IF ZWasA > 0 THEN _
  311.          ZDebug = -1 : _
  312.          WasPM$ = LEFT$(WasPM$,ZWasA - 1) + _
  313.                RIGHT$(WasPM$,LEN(WasPM$) - ZWasA - 4)
  314.       PassedDebug = ZDebug
  315.       ZWasA = INSTR(WasPM$,"LOCAL")
  316.       IF ZWasA > 0 THEN _
  317.          ZComPort$ = "COM0" : _
  318.          WasPM$ = LEFT$(WasPM$,ZWasA - 1) + _
  319.                RIGHT$(WasPM$,LEN(WasPM$) - ZWasA - 4)
  320.       IF LEN(WasPM$) = 0 THEN _
  321.          WasPM$ = "-"
  322.       ZNodeRecIndex = INSTR("-1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ",LEFT$(WasPM$,1))
  323.       IF ZNodeRecIndex < 2 THEN _
  324.          ZNodeRecIndex = 2
  325.       ZNodeID$ = MID$(STR$(ZNodeRecIndex-1),2)
  326.       IF ZNodeRecIndex > 10 THEN _
  327.          ZNodeFileID$ = LEFT$(WasPM$,1) _
  328.       ELSE ZNodeFileID$ = ZNodeID$
  329.       IF ZNodeID$ <> "1" THEN _
  330.          ZLibNodeID$ = ZNodeFileID$
  331.       IF LEN(WasPM$) > 2 AND MID$(WasPM$,2,1) = " " THEN _
  332.          ZConfigFileName$ = MID$(WasPM$,3)_
  333.       ELSE MID$(ZConfigFileName$,5,1) = WasPM$
  334.       ZOrigCnfg$ = ZConfigFileName$
  335.       END SUB
  336. 105 ' $SUBTITLE: 'Trim - sub to eliminate leading/trailing blanks'
  337. ' $PAGE
  338. '
  339. '  NAME    -- Trim
  340. '
  341. '  INPUTS  --  PARAMETER                    MEANING
  342. '              TrimParm$           STRING THAT IS TO HAVE LEADING
  343. '                                  AND TRAILING BLANKS ELIMINATED FROM
  344. '
  345. '  OUTPUTS --  TrimParm$           STRING WITH NO LEADING OR TRAILING
  346. '                                   BLANKS
  347. '
  348. '  PURPOSE --  To strip leading and trailing blanks
  349. '
  350.       SUB Trim (TrimParm$) STATIC
  351.       WasL = INSTR(TrimParm$," ")
  352.       IF WasL < 1 THEN _
  353.          EXIT SUB
  354.       IF WasL = 1 THEN _
  355.          WHILE LEFT$(TrimParm$,1) = " " : _
  356.             TrimParm$ = RIGHT$(TrimParm$,LEN(TrimParm$) - 1) : _
  357.          WEND
  358.       CALL TrimTrail (TrimParm$," ")
  359.       END SUB
  360. '
  361. 107 '  $SUBTITLE: 'TrimTrail - sub to trim off trailing characters'
  362. '  $PAGE
  363. '
  364. '  NAME    --  TrimTrail
  365. '
  366. '  INPUTS  --  PARAMETER           MEANING
  367. '              TrimParm$  WHAT STRING TO Trim FROM
  368. '              TrimThis$  WHAT CHARACTER TO Trim OFF END
  369. '
  370. '  OUTPUTS --  NONE
  371. '
  372. '  PURPOSE --  To remove all occurences of a character from end of string
  373. '
  374.       SUB TrimTrail (TrimParm$,TrimThis$) STATIC
  375.       IF RIGHT$(TrimParm$, 1) <> TrimThis$ THEN _
  376.          EXIT SUB
  377.       WasJ = LEN(TrimParm$) - 1
  378. 108   IF WasJ > 0 THEN _
  379.          IF MID$(TrimParm$, WasJ, 1) = TrimThis$ THEN _
  380.             WasJ = WasJ - 1 : _
  381.             GOTO 108
  382.       TrimParm$ = LEFT$(TrimParm$, WasJ)
  383.       END SUB
  384. '
  385. 109 '  $SUBTITLE: 'VarInit - subroutine to initialize system variables'
  386. '  $PAGE
  387. '
  388. '  NAME    --  VarInit
  389. '
  390. '  INPUTS  --  PARAMETER           MEANING
  391. '              NONE
  392. '
  393. '  OUTPUTS --  NONE
  394. '
  395. '  PURPOSE --  To initialize system variable
  396. '
  397.       SUB VarInit STATIC
  398.     ZAcknowledge$ = CHR$(6)
  399.     ZAckChar$ = "C" + _
  400.             ZAcknowledge$
  401.     ZActiveMenu$ = "B"
  402.     ZActiveMessage$ = CHR$(225)
  403.     ZBackSpace$ = CHR$(8) + _
  404.                  CHR$(32) + _
  405.                  CHR$(8)
  406.     ZBackArrow$ = CHR$(29) + _
  407.                   CHR$(32) + _
  408.                   CHR$(29)
  409.     ZBaudRates$ = "      300  450 1200 2400 4800 96001920038400"
  410.     ZBellRinger$ = CHR$(7)
  411.     ZBulletinMenu$ = ""
  412.     ZWasCL = 24
  413.     ZCancel$ = CHR$(24)
  414.     ZColorReset$ = CHR$(27) + _
  415.                    "[00;37;40m"
  416.     ZConfigFileName$ = "RBBS-PC.DEF"
  417.     ZCarriageReturn$ = CHR$(13)
  418.     ZDeletedMsg$ = CHR$(226)
  419.     ZDosVersion = 2
  420.     ZEndTransmission$ = CHR$(4)
  421.     ZEscape$ = CHR$(27)
  422.     ZExpectActiveModem = 0
  423.     ZFalse = 0
  424.     ZF1Key = 59
  425.     ZF10Key = 68
  426.     ZConfName$ = "MAIN"
  427.     CALL SetHiLite (ZTrue)
  428.     ZHomeConf$ = ""
  429.     ZInConfMenu = -1
  430.     ZLastCommand$ = "M "
  431.     ZLimitMinsPerSession = 0
  432.     ZLineFeed$ = CHR$(10)
  433.     ZLineFeeds = NOT ZFalse
  434.     ZLineEditChk$ = CHR$(9) + _
  435.                     ZLineFeed$ + _
  436.                     CHR$(11) + _
  437.                     CHR$(12) + _
  438.                     CHR$(127) + _
  439.                     CHR$(8) + _
  440.                     ZBellRinger$ + _
  441.                     CHR$(26) + _
  442.                     CHR$(227)
  443.     ZLineMes$ = SPACE$(78)          ' fixed length string workspace
  444.     ZLockStatus$ = "UM UU UB UD"
  445.     ZMenuIndex = 2
  446.     ZNAK$ = CHR$(21)
  447.     ZNoAdvance = ZFalse
  448.     ZPageLength = 23
  449.     ZParseOff = ZFalse
  450.     ZPressEnter$ = " (Press [ENTER] to quit)"
  451.     ZPressEnterExpert$ = " ([ENTER] quits)"
  452.     ZPressEnterNovice$ = ZPressEnter$
  453.     ZPrivateDoor = ZFalse
  454.     ZRightMargin = 72
  455.     ZReturnLineFeed$ = ZCarriageReturn$ + _
  456.                         ZLineFeed$
  457.     ZSmartTable$ = "CS PB NS FN LN SL DT TM TR TE TL RP RR CT " + _
  458.                    "C1 C2 C3 C4 C0 DD BD DB UB DL UL FI VY VN " + _
  459.                    "TY TN BN ND FS LS"
  460.     ZStartOfHeader$ = CHR$(1)
  461.     ZTimeLoggedOn$ = SPACE$(8)
  462.     ZTrue = NOT ZFalse
  463.     ZUpInc = -1
  464.     ZXOff$ = CHR$(19)
  465.     ZXOn$ = CHR$(17)
  466.     ZInterrupOn$ = CHR$(11) + ZCancel$ + ZXOff$ + ZXOn$ + ZCarriageReturn$
  467.     ZOptionEnd$ = ZReturnLineFeed$ + " ,("
  468.     ZCrLf$ = ZCarriageReturn$ + ZLineFeed$
  469.     ZWasLG$(1) = "Registration Check Failed"
  470.     ZWasLG$(2) = "Sysop name attempted"
  471.     ZWasLG$(3) = "Locked out attempt"
  472.     ZWasLG$(4) = "Password Attempt Failed"
  473.     ZWasLG$(5) = "Auto Lockout done"
  474.     ZWasLG$(6) = "Name in use on another Node!"
  475.     ZWasLG$(7) = ""
  476.     ZWasLG$(8) = "Locked reason read!"
  477.     ZWasLG$(9) = "Expired Registration"
  478.     END SUB
  479. '
  480. 112 ' $SUBTITLE: 'SysMenu - sub to display RBBS-PC SYSOP menu'
  481. '  $PAGE
  482. '
  483. '  NAME    --  SysMenu
  484. '
  485. '  INPUTS  --  PARAMETER           MEANING
  486. '
  487. '  OUTPUTS --  NONE
  488. '
  489. '  PURPOSE --  TO DISPLAY RBBS-PC's SYSOP MENU ON THE LOCAL SCREEN
  490. '
  491.     SUB SysMenu STATIC
  492.     ZLocalUser = ZTrue
  493.     ZSnoop = ZTrue
  494.     ZNonStop = ZTrue
  495.     CALL CheckTime (TIMER, ZDelay!, 1)
  496.     CLS
  497.     ZStopInterrupts = ZTrue
  498.     ZBypassTimeCheck = ZTrue
  499.     CALL BufFile ("MENU0",WasX)
  500.     ZNonStop = ZFalse
  501.     ZBypassTimeCheck = ZFalse
  502.     ZLocalUser = ZFalse
  503.     IF NOT ZOK THEN _
  504.        CALL LPrnt("MENU0 not on default drive",1)
  505.     LOCATE 2,18
  506.     CALL LPrnt(LEFT$(ZVersionID$,8),0)
  507.     LOCATE 2,42
  508.     CALL LPrnt(ZNodeID$,0)
  509.     LOCATE 2,60
  510.     WasX$ = DATE$
  511.     CALL LPrnt(LEFT$(WasX$,6) + RIGHT$(WasX$,2),0)
  512.     LOCATE 2,74
  513.     CALL LPrnt(LEFT$(TIME$,5),0)
  514.     IF ZFMSDirectory$ <> "" THEN _
  515.        LOCATE 6,76 : _
  516.        CALL LPrnt("YES",0)
  517.     IF ZExtendedLogging THEN _
  518.        LOCATE 8,76 : _
  519.        CALL LPrnt("YES",0)
  520.     IF ZFossil THEN _
  521.        LOCATE 10,76 : _
  522.        CALL LPrnt("YES",0)
  523.     LOCATE 12,75 : _
  524.     CALL LPrnt(ZComPort$,0)
  525.     LOCATE 14,75
  526.     CALL LPrnt (STR$(CINT(FRE("A")/1024)) + "k",0)
  527.     IF ZDebug THEN _
  528.        LOCATE 22,76 : _
  529.        CALL LPrnt("Yes",0)
  530.     END SUB
  531. '
  532. 120 '  $SUBTITLE: 'EditDef - sub to edit config parameters'
  533. '  $PAGE
  534. '
  535. '  NAME    -- EditDef
  536. '
  537. '  INPUTS  --     PARAMETER                    MEANING
  538. '
  539. '  OUTPUTS --                          OUTPUT STRING
  540. '
  541. '  PURPOSE -- Interpretes and adjusts stored configuration parameters
  542. '
  543.       SUB EditDef STATIC
  544.       ZAllOpts$ = ZMainCmds$ + _
  545.                   ZFileCmd$ + _
  546.                   ZUtilCmds$ + _
  547.                   ZLibCmds$ + _
  548.                   ZGlobalCmnds$ + _
  549.                   ZSysopCmds$
  550.       ZHelpExtension$ = "." + _
  551.                         ZHelpExtension$
  552.       ZCompressedExt$ = ZDefaultExtension$
  553.       ZWasQ = INSTR(ZDefaultExtension$,".")
  554.       IF ZWasQ > 0 THEN _
  555.          ZDefaultExtension$ = LEFT$(ZDefaultExtension$, ZWasQ-1)
  556.       ZCurDirPath$ = ZDirPath$
  557.       ZBegMain = 1
  558.       ZBegFile = LEN(ZMainCmds$) + ZBegMain
  559.       ZBegUtil = LEN(ZFileCmd$) + ZBegFile
  560.       ZBegLibrary = LEN(ZUtilCmds$) + ZBegUtil
  561.       ZHelp$(3) = ZHelpPath$ + _
  562.                  ZHelp$(3)
  563.       ZHelp$(4) = ZHelpPath$ + _
  564.                  ZHelp$(4)
  565.       ZHelp$(7) = ZHelpPath$ + _
  566.                  ZHelp$(7)
  567.       ZHelp$(9) = ZHelpPath$ + _
  568.                  ZHelp$(9)
  569.       CALL BreakFileName (ZWelcomeFile$,ZWelcomeFileDrvPath$,Prefix$,_
  570.                      Extension$,ZTrue)
  571.      CALL ASCIICodes ("[","]",ZDefaultLineACK$)
  572.      CALL ASCIICodes ("[","]",ZHostEchoOn$)
  573.      CALL ASCIICodes ("[","]",ZHostEchoOff$)
  574.      CALL ASCIICodes ("[","]",ZEmphasizeOffDef$)
  575.      CALL ASCIICodes ("[","]",ZEmphasizeOnDef$)
  576.      ZDR1$ = ZFG1Def$
  577.      ZDR2$ = ZFG2Def$
  578.      ZDR3$ = ZFG3Def$
  579.      ZDR4$ = ZFG4Def$
  580.      IF ZSubParm = -62 THEN _
  581.         EXIT SUB
  582.      ZLocalUserMode = (RIGHT$(ZComPort$,1) < "1")
  583.      IF ZLocalUserMode THEN _
  584.         ZRecycleToDos = ZTrue
  585.      ZEchoer$ = ZDefaultEchoer$
  586.      IF LEN(ZScreenOutMsg$) < 2 THEN _
  587.         ZScreenOutMsg$ = ZStartOfHeader$
  588.      ZSmartTextCode$ = CHR$(ZSmartTextCode)
  589.      IF ZMaxWorkVar < 13 THEN _
  590.         ZMaxWorkVar = 13
  591. '
  592. ' ***  ESTABLISH RBBS-PC'S DOS SUBDIRECTORIES USAGE  ***
  593. '
  594.     IF ZMainFMSDir$ <> "" THEN _
  595.        ZFMSDirectory$ = ZDirPath$ + _
  596.                         ZMainFMSDir$ + _
  597.                         "." + _
  598.                         ZMainDirExtension$ : _
  599.        ZActiveFMSDir$ = ZFMSDirectory$ : _
  600.        ZLibDir$ = ZLibDirPath$ + _
  601.                             ZMainFMSDir$ + _
  602.                             "." + _
  603.                             ZLibDirExtension$
  604.     ZUpcatHelp$ = ZHelpPath$ + _
  605.                   ZUpcatHelp$ + _
  606.                   ZHelpExtension$
  607.     IF ZSubDirCount < 1 THEN _
  608.        GOTO 123
  609.     FOR ZSubDirIndex = 1 TO ZSubDirCount
  610.        INPUT #2,ZSubDir$
  611.        IF RIGHT$(ZSubDir$,1) <> "\" THEN _
  612.          ZSubDir$(ZSubDirIndex) = ZSubDir$ + _
  613.                                  "\" _
  614.        ELSE ZSubDir$(ZSubDirIndex) = ZSubDir$
  615.     NEXT
  616.     GOTO 125
  617. 123 FOR ZSubDirIndex = 1 TO LEN(ZDnldDrives$) - 1
  618.        ZSubDir$(ZSubDirIndex) = MID$(ZDnldDrives$,ZSubDirIndex,1) + _
  619.                                ":"
  620.     NEXT
  621.     ZSubDirCount = LEN(ZDnldDrives$) - 1
  622. '
  623. ' *****  SETUP UPLOAD DRIVE AND DIRECTORY.NAME  ***
  624. '
  625. 125 ZUpldDirCheck$ = ZUpldDir$
  626.     ZSubDirCount = ZSubDirCount + 1
  627.     IF ZUpldToSubdir THEN _
  628.        ZSubDir$(ZSubDirCount) = ZUpldSubdir$ + _
  629.                                "\" _
  630.     ELSE ZSubDir$(ZSubDirCount) = RIGHT$(ZDnldDrives$,1) + _
  631.                                  ":"
  632.     ZUpldDir$ = ZUpldDir$ + _
  633.                         "." + _
  634.                         ZMainDirExtension$
  635.     CALL SearchArray (ZSubDir$(ZSubDirCount),ZSubDir$(),ZSubDirCount-1,Found)
  636.     ZCanDnldFromUp = (Found > 0)
  637.     ZUpldDir$ = ZUpldPath$ + _
  638.                         ZUpldDir$
  639. 126 CLOSE #2
  640.     IF ZLibDrive$ <> "" THEN _
  641.        ZLibType = 1
  642.     ZSubParm = -10
  643.     CALL Carrier
  644.     IF ZSubParm = -1 THEN _
  645.        IF ZLibDrive$ <> "" THEN _
  646.           CALL ChangeDir (ZLibDrive$ + _
  647.                          "\") : _
  648.           CALL KillWork (ZLibWorkDiskPath$ + _
  649.                         ZLibNodeID$ + _
  650.                         "DK*.ARC") : _
  651.                         ZErrCode = 0
  652. '
  653. ' ***  INITIALIZE OMNINET INTERFACE IF OMNINET IN USE  ***
  654. '
  655. 128 IF ZNetworkType = 2 THEN _
  656.        ZWasCN$ = SPACE$(535) : _
  657.        CALL InitIO(ZWasA)
  658.        END SUB
  659. '
  660. 129 '  $SUBTITLE: 'ASCIICodes - subrotuine to allow any ASCII codes'
  661. '  $PAGE
  662. '
  663. '  NAME    -- ASCIICodes
  664. '
  665. '  INPUTS  --     PARAMETER                    MEANING
  666. '                 LeftParen$           MARKS BEGINNING OF #
  667. '                 RightParen$          MARKS END OF #
  668. '                 Strng$                INPUT STRING
  669. '
  670. '  OUTPUTS --    Strng$                OUTPUT STRING
  671. '
  672. '  PURPOSE -- To allow a config string to have any ascii values.
  673. '             characters not enclosed taken as is.  Enclosed
  674. '             characters interpreted as value of ascii code.
  675. '             (e.g. "123[32]4" is interpreted as "123 4").
  676. '
  677.     SUB ASCIICodes (LeftParen$,RightParen$,Strng$) STATIC
  678.     IF LEN(Strng$) < 1 THEN _
  679.        EXIT SUB
  680.     Start = 1
  681.     WasL = LEN(Strng$)
  682.     ZUserIn$ = Strng$ + _
  683.          LeftParen$
  684.     WasX = INSTR(ZUserIn$,LeftParen$)
  685.     NewString$ = ""
  686.     WHILE Start <= WasL
  687.        NewString$ = NewString$ + _
  688.                     MID$(ZUserIn$,Start,WasX - Start)
  689.        WasY = INSTR(WasX,ZUserIn$,RightParen$)
  690.        IF WasY > 0 THEN _
  691.           WasK = VAL(MID$(ZUserIn$,WasX + 1,WasY - WasX - 1)) : _
  692.           NewString$ = NewString$ + _
  693.                        CHR$(WasK) : _
  694.           Start = WasY + 1 _
  695.        ELSE NewString$ = NewString$ + _
  696.                          MID$(ZUserIn$,WasX,WasL + 1 - WasX) : _
  697.             Start = WasL + 1
  698.        WasX = INSTR(Start,ZUserIn$,LeftParen$)
  699.     WEND
  700.     Strng$ = NewString$
  701.     END SUB
  702. 200 ' $SUBTITLE: 'AnswerIt - sub to establish connection'
  703. ' $PAGE
  704. '
  705. '  NAME    -- AnswerIt
  706. '
  707. '  INPUTS  --     PARAMETER                    MEANING
  708. '                 ZSubParm = 1           WAIT FOR PHONE TO RING
  709. '                          = 2           CONTINUE LOOKING FOR CONNECT
  710. '                          = 3           RENTRY AFTER FUNCTION KEY
  711. '                          = 4           GO ON LINE IMMEDIATELY
  712. '                 ZBG                    LOCAL DISPLAY'S BACKGROUND
  713. '                 ZBorder                LOCAL DISPLAY'S BORDER COLOR
  714. '                 ZComPort$              COMMUNICATIONS PORT NAME
  715. '                 ZComputerType          TYPE OF COMPUTER RUNNING ON
  716. '                 ZDumbModem             NON-HAYES TYPE MODEM FLAG
  717. '                 ZExtendedLogging       EXTENDED CALLERS LOG FLAG
  718. '                 ZFG                    LOCAL DISPLAY'S FOREGROUND
  719. '                 ZModemAnswerCmd$       COMMAND TO ANSWER PHONE
  720. '                 ZModemCntlReg          LOCATION WasOF MODEM CNTRL. REG
  721. '                 ZModemCountRingsCmd$   COMMAND TO COUNT PHONE RINGS
  722. '                 ZModemInitBaud$        BAUD AT WHICH TO OPEN COMM.
  723. '                 ZModemResetCmd$        COMMAND TO RESET THE MODEM
  724. '                 ZModemStatusReg        LOCATION OF MODEM STATUS REG
  725. '                 ZPrinter               FLAG TO PRINT ON LOCAL PRT.
  726. '                 ZRequiredRings         NUMBER OF RINGS TO ANSWER ON
  727. '                 ZSnoop                 FLAG TO DISPLAY ON LOCAL PC
  728. '                 ZSysopNext             FLAG TO GIVE SYSOP CONTROL
  729. '
  730. '  OUTPUTSS --    BaudTest!              BAUD RATE TO SET RS232 AT
  731. '                 ZEightBit              PARITY INDICATOR
  732. '                 ZReliableMode          INDICATES MODEM-SUPPLIED
  733. '                                        "ERROR-FREE" Protocol ACTIVE
  734. '                 ZSubParm          = 1  Carrier DETECT Found (I.E.
  735. '                                        MODEM AUTO-ANSWERED).
  736. '                                   = 2  ANSWERED THE PHONE AND
  737. '                                        Carrier DETECT OCCURRED.
  738. '                                   = 3  SYSOP HIT "ESC" KEY ON THE
  739. '                                        LOCAL KEYBOARD.
  740. '                                   = 4  ANSWERED THE PHONE BUT NO
  741. '                                        Carrier WAS DETECTED.
  742. '                                   = 5  COMM. BUFFER OVERFLOW.
  743. '                                   = 6  FUNCTION KEY PRESSED ON THE
  744. '                                        LOCAL KEYBOARD.
  745. '
  746. '  PURPOSE -- To detect incoming call and establish connection.
  747. '
  748.       SUB AnswerIt STATIC
  749.       ZErrCode = 0
  750.       ZReliableMode = ZFalse
  751.       ZFF = ZSubParm
  752.       ZSubParm = 0
  753.       ON ZFF GOTO 201,324,245,320
  754. '
  755. '
  756. ' *  INITIALIZE MODEM AND ANNOUNCE RBBS-PC IS UP AND READY FOR CALLS
  757. '
  758. '
  759. 201 ZSubParm = -10
  760.     CALL Carrier
  761.     IF ZSubParm = 0 THEN _
  762.        GOTO 210
  763. '
  764. '
  765. ' *  RESET THE MODEM VIA THE MODEM CONTROL REGISTER  TO ASSURE IT IS READY
  766. '
  767. '
  768.     IF ZFossil THEN _
  769.        State = 0 : _
  770.        CALL FosDTR(ZComPort,State) _
  771.     ELSE OUT ZModemCntlReg,&H4
  772.     CALL DelayTime (ZModemInitWaitTime)
  773. '
  774. '
  775. ' *  CLEAR THE MODEM CONTROL REGISTER PRIOR TO OPEN THE COMMUNICATIONS PORT
  776. '
  777. '
  778.     IF ZFossil THEN _
  779.        State = 1 : _
  780.        CALL FosDTR(ZComPort,State) _
  781.     ELSE OUT ZModemCntlReg,&H0
  782.     CALL DelayTime (ZModemInitWaitTime)
  783. 210 IF ZPrivateDoor THEN _
  784.        CALL Transfer : _
  785.        GOTO 235
  786.     CALL OpenCom(ZModemInitBaud$,",N,8,1")
  787. 220 CALL AMorPM
  788. 230 CALL Printit (" RBBS-PC " + ZVersionID$ + " Node " + _
  789.                     ZNodeID$ + " up " + ZTime$ + " on " + DATE$)
  790. 235 ZEightBit = ZTrue
  791.     ZSubParm = -10
  792.     CALL Carrier
  793.     IF ZSubParm = 0 AND _
  794.        ZExitToDoors THEN _
  795.        CALL ReadProf : _
  796.        ZSubParm = 1 : _
  797.        GOTO 335
  798.     IF ZSubParm = 0 AND _
  799.        ZExpectActiveModem THEN _
  800.        ZBaudTest! = VAL(ZNetBaud$) : _
  801.        CALL TestRel (ZNetReliable$) : _
  802.        GOTO 328
  803.     IF ZExpectActiveModem OR _
  804.        ZExitToDoors THEN _
  805.        ZSubParm = 4 : _
  806.        EXIT SUB
  807.     IF ZSubParm = 0 THEN _
  808.        ConnectDelay! = TIMER + ZMaxCarrierWait : _
  809.        GOTO 324
  810.     PCJr = ZFalse
  811.     IF ZComputerType = 2 AND _
  812.        ZComPort$ = "COM1" AND _
  813.        ZModemStatusReg = 1022 THEN _
  814.        ZModemGoOffHookCmd$ = CHR$(14) + _
  815.                                    "P" : _
  816.        PCJr = ZTrue
  817.     CALL SysMenu
  818.     IF PCJr THEN _
  819.        ZOutTxt$ = CHR$(14) + _
  820.             "I" _
  821.     ELSE ZOutTxt$ = ZModemResetCmd$
  822.     CALL ModemPut (ZOutTxt$)
  823.     CALL DelayTime (ZModemInitWaitTime)
  824.     IF PCJr THEN _
  825.        ZOutTxt$ = CHR$(14) + _   ' PC-JR'ZWasS MODEM COMMAND IDENTIFIER
  826.               "C 0," + _   ' SET "AUTO-ANSWER" OFF ON PC-JR'ZWasS MODEM
  827.               "S 1," + _   ' SET SPEED TO 300 BAUD ON PC-JR'ZWasS MODEM
  828.               "H" _        ' MANUALLY HANG UP THE PHONE (IF NOT ALREADY)
  829.     ELSE ZOutTxt$ = ZModemInitCmd$
  830.     CALL ModemPut (ZOutTxt$)
  831.     IF PCJr THEN _
  832.        ZOutTxt$ = CHR$(14) + _
  833.             "F 4" : _
  834.        CALL ModemPut (ZOutTxt$)
  835.     RingBack = ZFalse
  836.     LOCATE 16,55
  837.     IF ZRequiredRings = 0 THEN _
  838.        CALL LPrnt("WAITING FOR CARRIER",0) : _
  839.        GOTO 237
  840.     IF MID$(ZModemInitCmd$, _
  841.           INSTR(ZModemInitCmd$,"S0") + 3,3) = "255" THEN _
  842.        CALL LPrnt("RING BACK SYSTEM",0) : _
  843.        RingBack = ZTrue : _
  844.        GOTO 236
  845.     CALL LPrnt(" WAITING FOR RING ",0)
  846. 236 LOCATE 16,76 : _
  847.     CALL LPrnt(MID$(STR$(ZRequiredRings),2),0)
  848. 237 LOCATE 18,76
  849.     IF ZDosANSI THEN _
  850.        CALL LPrnt(ZEscape$ + "[05m" + "YES" + ZEscape$ + "[00m",0) _
  851.     ELSE CALL LPrnt ("YES",0)
  852.     COLOR ZFG,ZBG,ZBorder
  853.     LOCATE 20,56
  854. '
  855. '
  856. ' *  GET READY TO ANSWER INCOMMING CALL:
  857. ' *       1.  LET THE MODEM "AUTO-ANSWER" FOR RBBS-PC.
  858. ' *           REQUIRED RINGS = 0 AND S0 = 1 IN MODEM INIT COMMAND.
  859. ' *       2.  ANSWER THE MODEM ON A SPECIFIED NUMBER OF RINGS.
  860. ' *           REQUIRED RINGS > 0 AND S0 = 254 IN MODEM Init COMMAND.
  861. ' *       3.  ANSWER THE MODEM ON A SPECIFIED NUMBER OF RINGS AFTER A USER
  862. ' *           First CALLS AND THEN HANGS UP (I.E. RING-BACK).
  863. ' *           REQUIRED RINGS > 0 AND S0 = 255 IN MODEM INIT COMMAND.
  864. '
  865. '
  866.     WasQQ = 255
  867.     WasI = INSTR(ZModemInitCmd$,"S0")
  868.     IF WasI = 0 OR PCJr THEN _
  869.        GOTO 239
  870.     IF VAL(MID$(ZModemInitCmd$,WasI + 3,3)) = 255 THEN _
  871.        WasQQ = 0 : _
  872.        ZBlk = WasQQ
  873.     ZSecsUsedSession! = TIMER
  874.     ZSubParm = 1
  875.     CALL Line25
  876.     RingAnswer = ZTrue
  877.     IF RingBack THEN _
  878.        RingAnswer = ZFalse
  879. 239 RingBackWaitStart! = 0
  880.     IF RingBack THEN _
  881.        RingBackWaitStart! = TIMER : _
  882.        COLOR 7,0,0 _
  883.     ELSE COLOR ZFG,ZBG,ZBorder
  884. 240 IF ZSysopNext THEN _
  885.        ZSubParm = 3 : _
  886.        EXIT SUB
  887. '
  888. '
  889. ' * WAIT FOR INCOMING CALLS
  890. '
  891. '
  892.     ScreenCleared = ZFalse
  893. 245 InactiveDelay! = TIMER + (60 * ZRecycleWait)
  894.     NoCall = ZTrue
  895.     CALL FlushCom (ModemResponse$)
  896.     ModemResponse$ = ""
  897. 247 IF INP(ZModemStatusReg) > 127 OR (NOT NoCall) THEN _
  898.        GOTO 274
  899.        CALL FindFKey
  900.        IF ZSubParm < 0 THEN _
  901.           EXIT SUB
  902. 250    IF ZKeyPressed$ = ZEscape$ THEN _
  903.           ZSubParm = 3 : _
  904.           EXIT SUB
  905.        IF ZKeyPressed$ <> "" THEN _
  906.           GOTO 235
  907. 260    IF RingBackWaitStart! > 0 THEN _
  908.           CALL CheckTime(RingBackWaitStart!, TempElapsed!, 2) : _
  909.           IF TempElapsed! > 45 THEN _
  910.              RingBackWaitStart! = 0 : _
  911.              RingBackCount = 0 : _
  912.              RingAnswer = ZFalse: _
  913.              IF RingBack THEN _
  914.                LOCATE 20,56 : _
  915.                CALL LPrnt("Ringback timeout" + ZPagingPtrSupport$,1)
  916. 265    CALL CheckTime(ZSecsUsedSession!, TempElapsed!, 2)
  917.        IF TempElapsed! > 120 AND NOT ScreenCleared THEN _
  918.           LOCATE ,,0 : _
  919.           CLS : _
  920.           ZWasCL = 1 : _
  921.           ScreenCleared = ZTrue : _
  922.           ZSecsUsedSession! = TIMER
  923.        IF ZTimeToDropToDos! > 0 THEN _
  924.           IF ZOldDate$ <> DATE$ THEN _
  925.           IF TIMER => ZTimeToDropToDos! AND _
  926.              TIMER < 86340 THEN _      ' Skip btw 23:59 and 00:00
  927.                 ZSubParm = 7 : _
  928.                 EXIT SUB
  929. 266    IF (INP(ZModemStatusReg) AND &H40) > 0 AND _
  930.           ZRequiredRings > 0 THEN _
  931.           GOTO 276
  932. 270    IF ZRecycleWait > 0 THEN _
  933.           CALL CheckTime(InactiveDelay!, TempElapsed!, 1) : _
  934.           IF TempElapsed! <= 0 THEN _
  935.              ZSubParm = 8 : _
  936.              EXIT SUB
  937.        CALL FlushCom (WasX$)
  938.        IF LEN(WasX$) > 0 THEN _
  939.           ModemResponse$ = ModemResponse$ + WasX$ : _
  940.           RingDetected = (INSTR(ModemResponse$,"RING") > 0) : _
  941.           ConnectDetected = (INSTR(ModemResponse$,"ONNECT") > 0) : _
  942.           NoCall = (NOT RingDetected) AND (NOT ConnectDetected)
  943.     IF RingDetected AND ZRequiredRings > 0 THEN _
  944.        MID$(ModemResponse$, INSTR(ModemResponse$,"RING")+1,1) = "A" : _
  945.        RingDetected = ZFalse : _
  946.        GOTO 276
  947.     CALL GoIdle
  948.     GOTO 247
  949. 274 IF NOT RingBack THEN _
  950.        IF ConnectDetected THEN _
  951.           GOTO 321
  952.     IF ZRequiredRings = 0 THEN _
  953.        CALL DelayTime (3) : _
  954.        GOTO 321
  955. '
  956. '
  957. ' * PREPARE TO ANSWER THIS CALL ON A SPECIFIED NUMBER OF RINGS (S0 = 254) OR
  958. ' * THE CALL AFTER THIS CALL ON A SPECIFIED NUMBER OF RINGS (S0 = 255) --
  959. ' * "RING BACK."
  960. '
  961. '
  962. 276 CALL EofComm (Char)
  963.     IF Char <> -1 THEN _
  964.        CALL FlushCom(WasX$) : _
  965.        IF ZSubParm = - 1 THEN _
  966.           EXIT SUB
  967.     IF PCJr THEN _
  968.        GOTO 320
  969.     ZOutTxt$ = ZModemCountRingsCmd$
  970.     CALL ModemPut (ZOutTxt$)
  971.     CALL DelayTime (ZModemCmdDelayTime)
  972. 290 CALL FlushCom(WasX$)
  973.     IF ZSubParm = -1 THEN _
  974.        EXIT SUB
  975. 291 IF LEN(WasX$) = 0 THEN _
  976.        GOTO 310
  977. 292 IF INSTR(WasX$,"0") < 1 THEN _
  978.        GOTO 293
  979.     WasX$ = MID$(WasX$,INSTR(WasX$,"0"),4)
  980. 293 IF (NOT RingAnswer) AND (VAL(WasX$) < RingBackCount) THEN _
  981.        RingAnswer = ZTrue
  982. 300 RingBackCount = VAL(WasX$)
  983.     ZWasQ = RingBackCount + 1
  984.     IF (NOT RingAnswer) THEN _
  985.        ZWasQ = 0
  986. 305 LOCATE 20,56
  987.     CALL LPrnt(TIME$ + " Ring " + STR$(ZWasQ),0)
  988. 310 IF (RingBackCount + 1 < ZRequiredRings) OR _
  989.        (NOT RingAnswer) THEN _
  990.        GOTO 239
  991. 320 IF PCJr THEN _
  992.        ZOutTxt$ = CHR$(14) + _   ' PC-JR'S MODEM COMMAND IDENTIFIER
  993.             "T 0," + _     ' SET PC-JR'S MODEM TO TRANSPARENT MODE PERMANENTLY
  994.             "M" _          ' TELL THE PC-JR'S MODEM TO ANSWER IN DATA MODE
  995.     ELSE ZOutTxt$ = ZModemAnswerCmd$
  996.     CALL ModemPut (ZOutTxt$)
  997. '
  998. '
  999. ' *  TEST FOR Carrier PRESENT
  1000. '
  1001. '
  1002. 321 ConnectDelay! = TIMER + ZMaxCarrierWait
  1003. 322 CALL CheckTime(ConnectDelay!, TempElapsed!, 1)
  1004. 323 ZSubParm = -10
  1005.     CALL Carrier
  1006.     IF ZSubParm AND _
  1007.        TempElapsed! > 0 THEN _
  1008.        GOTO 322
  1009.     IF ZSubParm THEN _
  1010.        ZSubParm = 4 : _
  1011.        EXIT SUB
  1012.     CALL DelayTime (3)
  1013. 324 ZSubParm = 0
  1014.     CALL CheckTime(ConnectDelay!, TempElapsed!, 1)
  1015.     IF TempElapsed! <= 0 THEN _
  1016.        CALL UpdtCalr ("Connect timeout",1) : _
  1017.        ZSubParm = 4 : _
  1018.        EXIT SUB
  1019. 325 CALL FlushCom(WasX$)
  1020.     IF ZSubParm = -1 THEN _
  1021.        IF ZErrCode = 69 THEN _
  1022.           ZSubParm = 5 : _
  1023.        EXIT SUB
  1024.     ModemResponse$ = ModemResponse$ + WasX$
  1025.     IF LEN(ModemResponse$) > 200 THEN _
  1026.        ModemResponse$ = RIGHT$(ModemResponse$,20)
  1027.     CALL CheckTime(ConnectDelay!, TempElapsed!, 1)
  1028.     IF TempElapsed! <= 0 THEN _
  1029.        CALL UpdtCalr ("Connect timeout",1) : _
  1030.        ZSubParm = 4 : _
  1031.        EXIT SUB
  1032.     IF ZDumbModem THEN _
  1033.        ZBaudTest! = VAL(ZModemInitBaud$) : _
  1034.        GOTO 327
  1035.     IF INSTR(ModemResponse$,"FAST") THEN _
  1036.        ZBaudTest! = 19200 : _
  1037.        GOTO 327
  1038.     IF INSTR(ModemResponse$,"ONNECT") THEN _
  1039.        ZBaudTest! = VAL(MID$(ModemResponse$,INSTR(ModemResponse$,"ONNECT") + 7)) : _
  1040.        GOTO 327
  1041.     IF INSTR(ModemResponse$,"ONLINE") THEN _
  1042.        ZBaudTest! = VAL(MID$(ModemResponse$,INSTR(ModemResponse$,"ONLINE") + 7)) : _
  1043.        GOTO 327
  1044.     GOTO 324
  1045. 327 CALL TestRel (ModemResponse$)
  1046. 328 IF ZBaudTest! = 0 OR ZBaudTest! = 300 THEN _
  1047.        ZBaudTest! = 300 : _
  1048.        ZBPS = -1 : _
  1049.        GOTO 331
  1050.     IF ZBaudTest! = 1200 OR ZBaudTest! = 1275 THEN _
  1051.        ZBPS = -3 : _
  1052.        GOTO 331
  1053.     IF ZBaudTest! = 2400 THEN _
  1054.        ZBPS = -4 : _
  1055.        GOTO 331
  1056.     IF ZBaudTest! = 4800 OR ZBaudTest! = 9600 THEN _
  1057.        ZBPS = -4-(ZBaudTest! /4800) : _
  1058.        GOTO 331
  1059.     IF ZBaudTest! = 19200 THEN _
  1060.        ZBPS = -7 : _
  1061.        GOTO 331
  1062.     IF ZBaudTest! = 38400 THEN _
  1063.        ZBPS = -8 : _
  1064.        GOTO 331
  1065.     GOTO 324
  1066. 331 CALL SetBaud
  1067.     ZSubParm = 2
  1068. 335 DontWrite = 0
  1069.     END SUB
  1070. 336 ' $SUBTITLE: 'TestRel - Test for Reliable mode connection'
  1071. ' $PAGE
  1072. '
  1073. '  NAME    -- TestRel
  1074. '
  1075. '  INPUTS  --     PARAMETER                    MEANING
  1076. '                 Strng$                 String to check for reliable
  1077. '
  1078. '  OUTPUTS --    ZReliableMode          Reliable mode indicator
  1079. '
  1080. '  PURPOSE -- To test for reliable connect
  1081. '
  1082.     SUB TestRel (Strng$) STATIC
  1083.     ZReliableMode = ZFalse
  1084.     IF Strng$ = "" THEN _
  1085.        EXIT SUB
  1086.     IF INSTR(Strng$,"REL") OR _
  1087.        INSTR(Strng$,"R C") OR _       (ERROR CONTROL)
  1088.        INSTR(Strng$,"ARQ") OR _
  1089.        INSTR(Strng$,"LAP") OR _
  1090.        INSTR(Strng$,"AFT") OR _
  1091.        INSTR(Strng$,"MNP") THEN _
  1092.          ZReliableMode = -1
  1093.     END SUB
  1094. 455 ' $SUBTITLE: 'BadChar - sub to check user names for bad characters'
  1095. ' $PAGE
  1096. '
  1097. '  NAME    -- BadChar
  1098. '
  1099. '  INPUTS  --     PARAMETER                    MEANING
  1100. '                 PassedName$                  USER NAME
  1101. '
  1102. '  OUTPUTS --    PassedName$            USER NAME WILL CONTAIN ""
  1103. '                                       IF BAD CHARACTERS Found
  1104. '
  1105. '  PURPOSE -- To check user names for invalid characters
  1106. '
  1107.     SUB BadChar (PassedName$) STATIC
  1108.     WasJ = 1
  1109.     WasXX = LEN(PassedName$)
  1110. 457 IF WasJ > WasXX THEN _
  1111.        EXIT SUB
  1112.     WasX$ = MID$(PassedName$,WasJ,1)
  1113.     IF INSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZ '-./0123456789",WasX$) = 0 THEN _
  1114.        PassedName$ = "" : _
  1115.        EXIT SUB
  1116.     WasJ = WasJ + 1
  1117.     GOTO 457
  1118.     END SUB
  1119. 660 ' $SUBTITLE: 'PassWrd - verify User and Message passwords'
  1120. ' $PAGE
  1121. '
  1122. '  NAME    -- PassWrd
  1123. '
  1124. '  INPUTS  --     PARAMETER                    MEANING
  1125. '                 ZSubParm         = 1      VERIFY USER PASSWORD
  1126. '                                  = 2      VERIFY MESSAGE PASSWORD
  1127. '                                  = 3      VERIFY MESSAGE PASSWORD
  1128. '                                  = 4      VERIFY MESSAGE PASSWORD
  1129. '                                  = 5      VERIFY MESSAGE PASSWORD
  1130. '
  1131. '  OUTPUTS -- ZPswdFailed                   SET TO 0 IF PASSED
  1132. '                                           SET TO -1 IF FAILED
  1133. '
  1134. '  PURPOSE -- To verify user and message passwords
  1135. '
  1136.     SUB PassWrd STATIC
  1137.     ZErrCode = 0
  1138.     ON ZSubParm GOTO 665,667,670,675,677
  1139. 665 IF ZPswdSave$ = ZPswd$ THEN _
  1140.        ZPswdFailed = 0 : _
  1141.        EXIT SUB
  1142. 667 Attempts = 0
  1143. 670 Attempts = Attempts + 1
  1144.     IF Attempts > ZAttemptsAllowed THEN _
  1145.        ZPswdFailed = ZTrue : _
  1146.        EXIT SUB
  1147. 675 ZOutTxt$ = "Enter Password"
  1148.     ZHidden = ZTrue
  1149.     CALL PopCmdStack
  1150.     IF ZSubParm < 0 THEN _
  1151.        ZPswdFailed = ZTrue : _
  1152.        EXIT SUB
  1153.     ZHidden = ZFalse
  1154.     ZWasZ$ = ZUserIn$
  1155. 677 IF LEN(ZWasZ$) > 15 THEN _
  1156.        GOTO 680
  1157.     IF ZErrCode <> 0 THEN _
  1158.        GOTO 670
  1159.     CALL AllCaps (ZWasZ$)
  1160.     ZWasZ$ = ZWasZ$ + SPACE$(15 - LEN(ZWasZ$))
  1161.     IF ZPswdSave$ = ZWasZ$ THEN _
  1162.        ZPswdFailed = 0 : _
  1163.        ZOutTxt$ = "" : _
  1164.        EXIT SUB
  1165. 680 CALL QuickTPut1 ("Wrong password ")
  1166.     ZLastIndex = 0
  1167.     IF NOT ZMsgPswd THEN _
  1168.        CALL UpdtCalr (ZActiveUserName$+" PW fail: " + ZWasZ$,1)
  1169.     GOTO 670
  1170.     END SUB
  1171. 945 ' $SUBTITLE: 'Line25 - sub to build/display RBBS-PCs line 25'
  1172. ' $PAGE
  1173. '
  1174. '  NAME    -- Line25
  1175. '
  1176. '  INPUTS  --     PARAMETER                    MEANING
  1177. '                 ZSubParm           = 1  BUILD DISPLAY FOR LINE 25
  1178. '                                    = 2  UPDATE LINE 25
  1179. '                 ZLockStatus$            STATUS OF LOCKS IN A MULTI-
  1180. '                                         USER ENVIRONMENT OR TIME OF
  1181. '                                         DAY USER LOGGED ON OR THE
  1182. '                                         RE-CYCLED
  1183. '
  1184. '  OUTPUTS -- ZCursorLine                 CURRENT LINE ON SCREEN
  1185. '             ZCursorRow                  CURRENT ROW ON ZCursorLine
  1186.  
  1187. '
  1188. '  PURPOSE -- To build or update RBBS-PC's line 25 displayed
  1189. '             on the PC screen that is running RBBS-PC.
  1190. '
  1191.       SUB Line25 STATIC
  1192.       IF ZSubParm = 2 THEN _
  1193.          GOTO 950
  1194. '
  1195. '
  1196. ' *  BUILD LINE 25 DISPLAY
  1197. '
  1198. '
  1199. 949 ZLine25$ = "Node " + _
  1200.                ZNodeID$ + " " + _
  1201.                ZPageStatus$ + " " + _
  1202.                MID$("    AVL ",1 - 4 * ZSysopAvail,4) + _
  1203.                MID$("    ANY ",1 - 4 * ZSysopAnnoy,4) + _
  1204.                MID$("    LPT ",1 - 4 * ZPrinter,4) + _
  1205.                MID$("SYS",1,-3 * ZSysopNext) + _
  1206.                MID$(" XOFF",1,-5 * ZXOffEd) + _
  1207.                MID$(" CTS",1,-4 * ZNotCTS)
  1208. '
  1209. '
  1210. ' *  LINE 25 UPDATE ROUTINE
  1211. '
  1212. '
  1213. 950 IF NOT ZSnoop THEN _
  1214.        EXIT SUB
  1215.     ZCursorLine = CSRLIN
  1216.     ZCursorRow = POS(0)
  1217.     ZWasHH = LEN(ZActiveUserName$) + _
  1218.          LEN(ZWasCI$) + _
  1219.          LEN(ZLine25$) + _
  1220.          LEN(STR$(ZUserSecLevel)) + _
  1221.          18
  1222.     IF ZAutoDownYes THEN _
  1223.        ZWasHH = ZWasHH + 4
  1224.     LOCATE 25,1
  1225.     IF ZNetworkType = 0 THEN _
  1226.        IF ZAutoDownYes THEN _
  1227.           ZLockStatus$ = SPACE$(3) + _
  1228.                          "AD  " + _
  1229.                          ZTimeLoggedOn$ _
  1230.        ELSE ZLockStatus$ = SPACE$(3) + _
  1231.                            ZTimeLoggedOn$
  1232.     IF ZWasHH > 79 THEN _
  1233.        ZWasHH = 78
  1234.     ZLine25Hold$ = ZLine25$ + _
  1235.                     SPACE$(79 - ZWasHH) + _
  1236.                     STR$(ZUserSecLevel) + _
  1237.                     " " + _
  1238.                     ZActiveUserName$ + _
  1239.                     " " + _
  1240.                     ZWasCI$ + _
  1241.                     " " + _
  1242.                     ZLockStatus$
  1243.     TempBasicWrites = ZUseBASICWrites
  1244.     ZUseBASICWrites = ZTrue
  1245.     CALL LPrnt(ZLine25Hold$,0)
  1246.     ZUseBASICWrites = TempBasicWrites
  1247.     LOCATE ZCursorLine,ZCursorRow
  1248.     END SUB
  1249. 1238 ' $SUBTITLE: 'SearchCmd    - sub to search command list'
  1250. ' $PAGE
  1251. '
  1252. '  NAME    -- SearchCmd
  1253. '
  1254. '  INPUTS  -- PARAMETER             MEANING
  1255. '             StartPos         POSITION TO BEGIN SEARCH AT
  1256. '             ZAllOpts$        STRING TO SEARCH (COMMAND LIST)
  1257. '             ZWasZ$            WHAT TO LOOK FOR
  1258. '
  1259. '  OUTPUTS -- WhereFound   POSITION OF ZWasZ$ IN ZAllOpts$
  1260. '                           0 IF NOT Found
  1261. '
  1262. '  PURPOSE -- Searches valid command list for the requested
  1263. '             command.  If the sysop has configured RBBS-PC to
  1264. '             restrict commands to only those valid within the
  1265. '             RBBS-PC subsystem, then only those commands and
  1266. '             "GLOBAL" commands are valid.  Otherwise all commands
  1267. '             are valid from any of the RBBS-PC subsections.
  1268. '
  1269.      SUB SearchCmd (StartPos,WhereFound) STATIC
  1270. 1240 IF LEN(ZWasZ$) < 1 THEN _
  1271.         WhereFound = 0 : _
  1272.         EXIT SUB
  1273.      CALL Trim (ZWasZ$)
  1274.      CALL AllCaps (ZWasZ$)
  1275.      ZWasY$ = LEFT$(ZWasZ$,1)
  1276.      WhereFound = INSTR(StartPos,ZAllOpts$,ZWasY$)
  1277.      IF WhereFound = 0 THEN _  'Not found: decide whether to hunt further
  1278.         IF StartPos < 2 OR ZRestrictValidCmds THEN _
  1279.            GOTO 1242 _  ' fully searched or restricted
  1280.         ELSE WhereFound = INSTR(1,ZAllOpts$,ZWasY$) : _ 'hunt further
  1281.              GOTO 1242
  1282.      IF WhereFound => ZBegLibrary THEN _
  1283.         IF WhereFound < LEN(ZAllOpts$) - 11 THEN _
  1284.            IF ZLibType = 0 THEN _
  1285.               WhereFound = INSTR(WhereFound+1,AllOpt$,ZWasY$) : _
  1286.               IF WhereFound = 0 THEN _
  1287.                  WhereFound = INSTR(1,ZAllOpts$,ZWasY$) : _
  1288.                  IF WhereFound >= ZBegLibrary OR WhereFound = 0 THEN _
  1289.                     WhereFound = 0 : _
  1290.                     GOTO 1242
  1291.      IF NOT ZRestrictValidCmds THEN _
  1292.         GOTO 1242            ' everything found valid
  1293. '
  1294. '
  1295. ' * RESTRICT COMMANDS TO SUBSYSTEMS (EXCEPT GLOBAL AND SYSOP)
  1296. '
  1297. '
  1298.      IF WhereFound > LEN(ZAllOpts$) - 11 THEN _
  1299.         IF ZUserSecLevel < ZOptSec(WhereFound) THEN _
  1300.            WhereFound = 0 : _
  1301.            EXIT SUB _
  1302.         ELSE GOTO 1242
  1303.      IF MID$(ZOrigCommands$,WhereFound,1) = "G" THEN _
  1304.         GOTO 1242          ' ACCEPT GOODBYE/GRAPHICS
  1305.      IF (WhereFound < StartPos) OR _
  1306.         (StartPos < ZBegFile AND WhereFound => ZBegFile ) OR _
  1307.         (StartPos < ZBegUtil AND WhereFound => ZBegUtil ) OR _
  1308.         (StartPos < ZBegLibrary AND WhereFound => ZBegLibrary ) THEN _
  1309.            WhereFound = 0                 ' REJECT: NOT IN Section
  1310. 1242 IF WhereFound > 0 THEN _
  1311.         LSET ZLastCommand$ = ZActiveMenu$ + MID$(ZOrigCommands$,WhereFound) : _
  1312.         EXIT SUB
  1313.      IF ZMacroActive OR LEN(ZWasZ$) <> 1 THEN _
  1314.         EXIT SUB
  1315.      CALL Macro (ZWasZ$,Found)
  1316.      IF Found THEN _
  1317.         CALL FDMACEXE : _
  1318.         ZWasZ$ = ZUserIn$(1) : _
  1319.         GOTO 1240
  1320.      END SUB
  1321. 1320 ' $SUBTITLE: 'CheckMacro - sub to check if macro exists & process'
  1322. ' $PAGE
  1323. '
  1324. '  NAME    -- CheckMacro
  1325. '
  1326. '  INPUTS  -- PARAMETER             MEANING
  1327. '             Strng$               STRING TO CHECK IF IS A MACRO
  1328. '             ZMacroDrvPath$       DRIVE/PATH WHERE MACROS ARE
  1329. '             ZMacroExtension$     EXTENSION WasOF MACROS
  1330. '             MACRO.OFF            FORCE NO MACRO TO BE Found
  1331. '
  1332. '  OUTPUTS -- MacroFound           WHETHER A MACRO WAS Found
  1333. '             Strng$               SUBSTITUTE FOR COMMANDS
  1334. '             ZCommPortStack$      REST OF MACRO
  1335. '                                  0 IF NOT Found
  1336. '
  1337. '  PURPOSE -- Macro file is checked for security (1st line).
  1338. '             2nd line is substituted for passed string
  1339. '             and parsed.  Remaining part of macro put into
  1340. '             stack to be executed.
  1341. '
  1342.      SUB CheckMacro (Strng$,MacroFound) STATIC
  1343.      MacroFound = ZFalse
  1344.      IF ZMacroExtension$ = "" OR INSTR(Strng$,".") > 0 THEN _
  1345.         EXIT SUB
  1346.      IF LEN(Strng$) < ZMacroMin THEN _
  1347.         ZMacroMin = 1 : _
  1348.         EXIT SUB
  1349.      IF LEN(Strng$) = 1 THEN _
  1350.         Temp$ = Strng$ : _
  1351.         CALL AllCaps (Temp$) : _
  1352.         IF INSTR(ZAllOpts$,Temp$) > 0 THEN _
  1353.            EXIT SUB
  1354.      CALL Macro (Strng$,MacroFound)
  1355.      END SUB
  1356. 1325 ' $SUBTITLE: 'Macro - check if macro exists & process'
  1357. ' $PAGE
  1358. '
  1359. '  NAME    -- Macro
  1360. '
  1361. '  INPUTS  -- PARAMETER             MEANING
  1362. '             Strng$           STRING TO CHECK IF IS A MACRO
  1363. '             ZMacroDrvPath$   DRIVE/PATH WHERE MACROS ARE
  1364. '             ZMacroExtension$ EXTENSION OF MACROS
  1365. '             MACRO.OFF        FORCE NO MACRO TO BE Found
  1366. '
  1367. '  OUTPUTS -- MacroFound       WHETHER A MACRO WAS Found
  1368. '             Strng$           SUBSTITUTE FOR COMMANDS
  1369. '             ZCommPortStack$  REST OF MACRO
  1370. '                              0 IF NOT Found
  1371. '
  1372. '  PURPOSE -- Executes a macro if found.  Does not check if macro
  1373. '             letter uses a command.
  1374.      SUB Macro (Strng$,MacroFound) STATIC
  1375.      MacroFound = ZFalse
  1376.      Temp$ = Strng$
  1377.      CALL BreakFileName (Temp$,ZWasDF$,Prefix$,WasX$,ZFalse)
  1378.      IF Temp$ = Prefix$ THEN _
  1379.         FilName$ = ZMacroDrvPath$ + Strng$ + ZMacroExtension$ _
  1380.      ELSE FilName$ = Strng$
  1381.      CALL BadFile (FilName$,ZWasA)
  1382.      IF ZWasA > 1 THEN _
  1383.         EXIT SUB
  1384.      CALL GRAPHICX (ZUserGraphicDefault$,FilName$,6)
  1385.      IF NOT ZOK THEN _
  1386.         EXIT SUB
  1387.      CALL ReadDir (6,1)
  1388.      IF ZErrCode > 0 THEN _
  1389.         EXIT SUB
  1390.      CALL CheckInt (ZOutTxt$)
  1391.      IF ZErrCode > 0 OR ZUserSecLevel < ZTestedIntValue THEN _
  1392.         EXIT SUB
  1393.      ZWasA = INSTR(ZOutTxt$,"/")
  1394.      IF ZWasA > 0 THEN _    ' Check macro contraint
  1395.         WasX$ = RIGHT$(ZOutTxt$,LEN(ZOutTxt$)-ZWasA) : _
  1396.         IF RIGHT$(WasX$,1) = "/" THEN _
  1397.            IF ZLastCommand$ <> LEFT$(WasX$,LEN(WasX$)-1) THEN _
  1398.               EXIT SUB _
  1399.            ELSE GOTO 1327 _
  1400.         ELSE IF LEFT$(ZLastCommand$,LEN(WasX$)) <> WasX$ THEN _
  1401.                 EXIT SUB
  1402. 1327 ZMacroActive = ZTrue
  1403.      MacroFound = ZTrue
  1404.      ZMacroEcho = ZTrue
  1405.      END SUB
  1406. 1330 ' $SUBTITLE: 'ViewHelp    - Processes requests for help'
  1407. ' $PAGE
  1408. '
  1409. '  NAME    -- ViewHelp
  1410. '
  1411. '  INPUTS  -- PARAMETER             MEANING
  1412. '            Section             ORDER OF 1ST COMMAND IN CURRENT
  1413. '                                Section
  1414. '            GRAPHICS.DEFAULT    WHAT GRAPHICS TYPE USER WANTS
  1415. '            HelpDefault$        HELP GET IF PRESS ENTER
  1416. '            ZHelpPath$
  1417. '            ZHelpExtension$
  1418. '            ZBegFile
  1419. '            ZBegMain
  1420. '            ZBegUtil
  1421. '            ZBegLibrary
  1422. '
  1423. '  OUTPUTS -- DISPLAYS HELP
  1424. '
  1425. '  PURPOSE -- The main help processor for RBBS.  Puts up the
  1426. '             optional menu.  Accepts help with individual commands.
  1427. '
  1428.      SUB ViewHelp (Section,GraphicDefault$,HelpDefault$) STATIC
  1429.      HelpMenu$ = ZHelpPath$ + _
  1430.                   "HELP" + _
  1431.                   ZHelpExtension$
  1432.      SotMenu = ZTrue
  1433.      IF ZWasQ > 1 THEN _
  1434.         ZAnsIndex = 2 : _
  1435.         ZLastIndex = ZWasQ: _
  1436.         FastHelp = ZTrue : _
  1437.         GOTO 1332
  1438. 1331 IF SotMenu THEN _
  1439.         ZFileName$ = HelpMenu$ : _
  1440.         GOSUB 1350 : _
  1441.         SotMenu = ZFalse
  1442.      ZAnsIndex = 1
  1443.      ZOutTxt$ = "Help with what Command (or TOPIC name)" + _
  1444.           ZPressEnterExpert$
  1445.      ZSubParm = 1
  1446.      CALL TGet
  1447.      IF ZSubParm = -1 THEN _
  1448.         EXIT SUB
  1449.      IF ZWasQ = 0 THEN _
  1450.         EXIT SUB
  1451.      ZLastIndex = ZWasQ
  1452. 1332 ZWasZ$ = ZUserIn$(ZAnsIndex)
  1453.      CALL AllCaps (ZWasZ$)
  1454.      IF ZWasZ$ = "?" THEN _
  1455.         ZWasZ$ = "H"
  1456.      CALL BadFile (ZWasZ$,BadFileNameIndex)
  1457.      ON BadFileNameIndex GOTO 1333,1340,1340
  1458. 1333 IF LEN(ZWasZ$) <> 1 THEN _
  1459.         GOTO 1335
  1460.      CALL SearchCmd (Section,ZFF)
  1461.      IF ZFF < 1 THEN _
  1462.         ZOK = ZFalse : _
  1463.         GOTO 1336
  1464.      IF ZFF > LEN(ZAllOpts$) - 11 THEN _
  1465.         IF ZFF > LEN(ZAllOpts$) - 7 AND NOT ZSysop THEN _
  1466.            ZOK = ZFalse : _
  1467.            GOTO 1336 _
  1468.         ELSE ZWasZ$ = MID$(ZOrigCommands$,ZFF,1) : _
  1469.              GOTO 1335 _
  1470.      ELSE WasX = - (ZFF => ZBegMain) - (ZFF => ZBegFile) - (ZFF => ZBegUtil) - (ZFF => ZBegLibrary) : _
  1471.           ZWasZ$ = MID$("MFU@",WasX,1) + _
  1472.                    MID$(ZOrigCommands$,ZFF,1)
  1473. 1335 ZFileName$ = ZHelpPath$ + _
  1474.                   ZWasZ$ + _
  1475.                   ZHelpExtension$
  1476.      GOSUB 1350
  1477. 1336 IF NOT ZOK THEN _
  1478.         ZOutTxt$ = "No help for " + _
  1479.              ZWasZ$ : _
  1480.         CALL QuickTPut1 (ZOutTxt$) : _
  1481.         CALL UpdtCalr (ZOutTxt$,2)
  1482.      ZAnsIndex = ZAnsIndex + 1
  1483.      IF ZAnsIndex <= ZLastIndex THEN _
  1484.         GOTO 1332
  1485.      IF FastHelp THEN _
  1486.         FastHelp = ZFalse : _
  1487.         EXIT SUB
  1488.      GOTO 1331
  1489. 1340 ZOK = ZFalse
  1490.      GOTO 1336
  1491. 1350 CALL Graphic (GraphicDefault$,ZFileName$)
  1492.      CALL BufFile (ZFileName$,WasX)
  1493.      RETURN
  1494.      END SUB
  1495. 1380 ' $SUBTITLE: 'VIOLATION - handles all security violations'
  1496. ' $PAGE
  1497. '
  1498. '  NAME    -- SecViolation
  1499. '
  1500. '  INPUTS  --     PARAMETER                    MEANING
  1501. '
  1502. '  OUTPUTS -- ZCursorLine               CURRENT LINE ON SCREEN
  1503. '             ZCursorRow                CURRENT ROW ON ZCursorLine
  1504. '
  1505. '  PURPOSE -- Inform caller of security violation, augment count of
  1506. '             violations and determine whether too many occurred.
  1507. '
  1508.      SUB SecViolation STATIC
  1509.      CALL FlushKeys
  1510.      CALL BufFile (ZSecVioHelp$,WasX)
  1511.      IF NOT ZOK THEN _
  1512.         CALL QuickTPut1 ("Sorry, " + ZFirstName$ + ", action not permitted")
  1513.      CALL UpdtCalr ("SV!-" + ZViolation$,2)
  1514.      ZLastIndex = 0
  1515.      CALL Muzak (3)
  1516.      ZViolationsThisSession = ZViolationsThisSession + 1
  1517.      IF ZMaxViolations = 0 OR ZViolationsThisSession <= ZMaxViolations THEN _
  1518.         EXIT SUB
  1519. 1385 IF ZUserFileIndex < 1 THEN _
  1520.         EXIT SUB
  1521.      ZOutTxt$ = "SECURITY VIOLATION!  Sysop can reinstate"
  1522.      IF ZUserSecLevel <= ZMinLogonSec THEN _
  1523.         ZOutTxt$ = "" : _
  1524.         ZUserSecLevel = ZUserSecLevel - 1 _
  1525.      ELSE ZUserSecLevel = ZMinLogonSec
  1526.      ZDenyAccess = ZTrue
  1527.      END SUB
  1528. 1386 ' $SUBTITLE: 'DenyAccess - sub to permanently deny access'
  1529. ' $PAGE
  1530. '
  1531. '  NAME    -- DenyAccess
  1532. '
  1533. '  INPUTS  --     PARAMETER                    MEANING
  1534. '
  1535. '  OUTPUTS -- (USER'S RECORD)
  1536. '
  1537. '  PURPOSE -- Permanently resets user's security level when access denied
  1538. '
  1539.      SUB DenyAccess STATIC
  1540.      CALL TPut
  1541.      ZLogonErrorIndex = 5
  1542.      ZSubParm = 6
  1543.      CALL FileLock
  1544.      CALL OpenUser (HighestUserRecord)
  1545.      FIELD 5, 128 AS ZUserRecord$
  1546.      GET 5,ZUserFileIndex
  1547.      MID$(ZUserRecord$,47,2) = MKI$(ZUserSecLevel)
  1548.      PUT 5,ZUserFileIndex
  1549.      ZSubParm = 8
  1550.      CALL FileLock
  1551.      END SUB
  1552. 1396 ' $SUBTITLE: 'TPut -- common routine to write to comm. port'
  1553. ' $PAGE
  1554. '
  1555. '  NAME    -- TPut (TERMINAL PUT)
  1556. '
  1557. '  INPUTS  --     PARAMETER                    MEANING
  1558. '                     ZOutTxt$                 STRING TO WRITE TO THE
  1559. '                                              COMMUNICATIONS PORT
  1560. '                 ZSubParm = 1           SKIP A LINE BEFORE WRITING
  1561. '                                        TO THE COMMUNICATIONS PORT
  1562. '                          = 2           SKIP A LINE BEFORE WRITING
  1563. '                                        TO THE COMMUNICATIONS PORT
  1564. '                                        AND THEN SKIP TWO LINES
  1565. '                                        AFTER WRITING TO THE COMM-
  1566. '                                        UNICATIONS PORT
  1567. '                           = 3          WRITE TO THE COMMUNICATIONS
  1568. '                                        PORT AND THEN SKIP TWO LINES
  1569. '                           = 4          WRITE TO THE COMMUNICATIONS
  1570. '                                        PORT WITHOUT A CR/LF
  1571. '                           = 5          WRITE TO THE COMMUNICATIONS
  1572. '                                        PORT WITH A CR/LF
  1573. '                           = 6          RESET EVERYTHING FOR INPUT STRING
  1574. '                           = 7          RE-ENTRY AFTER HANDLING A
  1575. '                                        FUNCTION KEY
  1576. '
  1577. '  OUTPUTS --  ZSubParm = -1 Carrier HAS BEEN DROPPED
  1578. '              ZFunctionKey        <>  0 FUNCTION KEY PRESSED
  1579. '
  1580. '  PURPOSE --  Common output routine for RBBS-PC to the
  1581. '              communications port (terminal put)
  1582.       SUB TPut STATIC
  1583.       IF ZSubParm <> 7 THEN _
  1584.          Parm = ZSubParm
  1585.       ON ZSubParm GOTO 1398,1399,1400,1403,1405,1450,1411
  1586. '
  1587. '
  1588. ' *  COMMON OUTPUT ROUTINE
  1589. '
  1590. '
  1591. 1398 CALL SkipLine (1)
  1592.      GOTO 1405
  1593. 1399 CALL SkipLine (1)
  1594. 1400 ZCR = 1
  1595. 1403 ZCR = ZCR + 1
  1596. 1405 ZRet = ZFalse
  1597.      IF ZWasCM THEN _
  1598.         GOTO 1435
  1599. 1410 CALL FindFKey
  1600.      IF ZSubParm < 0 THEN _
  1601.         EXIT SUB
  1602. 1411 ZWasY$ = ZKeyPressed$
  1603.      ZSubParm = Parm
  1604.      IF ZLocalUser THEN _
  1605.         GOTO 1430
  1606.      CALL EofComm (Char)
  1607.      IF Char = -1 THEN _
  1608.         CALL CheckCarrier : _
  1609.         IF ZSubParm = -1 THEN _
  1610.            EXIT SUB _
  1611.         ELSE GOTO 1430
  1612.      CALL GetCom(ZWasY$)
  1613. 1425 IF ZSubParm = -1 THEN _
  1614.         EXIT SUB
  1615. 1430 IF ZWasY$ = "" THEN _
  1616.         GOTO 1435
  1617.      ON INSTR(ZInterrupOn$,ZWasY$) GOTO 1434,1434,1473,1475,1433
  1618.      GOSUB 1476
  1619.      GOTO 1435
  1620. 1433 GOSUB 1476
  1621.      IF ASC(RIGHT$(ZCommPortStack$,2)) = 13 OR _
  1622.         ZStopInterrupts THEN _
  1623.         GOTO 1435  'stack if series of [ENTER]s or no previous stack
  1624.      GOTO 1471
  1625. 1434 IF ZStopInterrupts THEN _
  1626.         GOTO 1435
  1627.      ZCommPortStack$ = ""
  1628.      IF ZFossil THEN _
  1629.         CALL FOSTXPurge(ZComPort) : _
  1630.         CALL FosRXPurge(ZComPort)
  1631.      GOTO 1471
  1632. 1435 LOCATE ,,1
  1633.      CALL LPrnt (ZOutTxt$,0)
  1634. 1437 IF ZUpperCase THEN _
  1635.         IF ZWasGR <> 2 THEN _
  1636.            CALL AllCaps (ZOutTxt$)
  1637.      CALL PutCom (ZOutTxt$)
  1638. 1450 IF ZCR <> 1 THEN _
  1639.         CALL SkipLine (1) _
  1640.      ELSE IF ZCR > 1 THEN _
  1641.              CALL SkipLine (1)
  1642. 1470 ZCR = 0
  1643.      EXIT SUB
  1644. 1471 CALL SkipLine (1)
  1645.      ZStopInterrupts = ZFalse
  1646.      ZRet = ZTrue
  1647.      ZNo = ZTrue
  1648.      ZNonStop = ZFalse
  1649.      GOTO 1470
  1650. 1473 ZXOffEd = ZTrue
  1651.      GOTO 1410
  1652. 1475 ZXOffEd = ZFalse
  1653.      GOTO 1410
  1654. 1476 IF ASC(ZWasY$) < 127 THEN _
  1655.         ZCommPortStack$ = ZCommPortStack$ + ZWasY$
  1656.      RETURN
  1657.      END SUB
  1658. 1478 ' $SUBTITLE: 'QuickTPut - subroutine to quickly write to terminal'
  1659. ' $PAGE
  1660. '
  1661. '  NAME    -- QuickTPut
  1662. '
  1663. '  INPUTS  -- PARAMETER             MEANING
  1664. '             Strng$             STRING TO WRITE OUT
  1665. '             NumReturns         NUMBER OF CARRIAGE RETURNS
  1666. '
  1667. '  OUTPUTS -- NONE
  1668. '
  1669. '  PURPOSE -- Subroutine to quickly write to the terminal.  This is
  1670. '             different from "TPut" in the things it doesn't do:
  1671. '                A.) No function key check,
  1672. '                B.) No conversion to upper case,
  1673. '                C.) No check for carrier present
  1674. '                D.) No check for imbedded carriage return in "Strng$"
  1675. '                E.) No support for XON/XOff
  1676. '
  1677.       SUB QuickTPut (Strng$,NumReturns) STATIC
  1678.       IF ZSubParm < 0 THEN _
  1679.          EXIT SUB
  1680.       IF ZUseTPut THEN _
  1681.          ZOutTxt$ = Strng$ : _
  1682.          ZSubParm = 4 : _
  1683.          CALL TPut : _
  1684.          CALL SkipLine (NumReturns) : _
  1685.          EXIT SUB
  1686.       CALL PutCom (Strng$)
  1687.       LOCATE ,,1
  1688.       CALL LPrnt (Strng$,0)
  1689.       CALL SkipLine (NumReturns)
  1690.       END SUB
  1691.       SUB QuickTPut1 (Strng$) STATIC
  1692.       CALL QuickTPut (Strng$,1)
  1693.       END SUB
  1694. 1480 ' $SUBTITLE: 'LPrnt    - subroutine to write to display'
  1695. ' $PAGE
  1696. '
  1697. '  NAME    -- LPrnt
  1698. '
  1699. '  INPUTS  -- PARAMETER             MEANING
  1700. '             Strng$        STRING TO WRITE OUT
  1701. '             NumReturns   NUMBER OF CARRIAGE RETURNS
  1702. '
  1703. '  OUTPUTS -- NONE
  1704. '
  1705. '  PURPOSE -- Subroutine to write to the display.
  1706. '
  1707.       SUB LPrnt (Strng$,NumReturns) STATIC
  1708.       IF NOT ZSnoop THEN _
  1709.          EXIT SUB
  1710.       CALL PScrn (Strng$)
  1711.       IF ZVoiceType <> 0 AND ZTalkAll THEN _
  1712.          CALL Talk (65,Strng$)
  1713.       IF ZUseBASICWrites THEN _
  1714.          FOR WasI = 1 TO NumReturns : _
  1715.             PRINT : _
  1716.          NEXT : _
  1717.       ELSE FOR WasI = 1 TO NumReturns : _
  1718.               LOCATE ,,1 : _
  1719.               CALL ANSI(ZCrLf$,ZWasCL,ZWasCC) : _
  1720.               LOCATE ZWasCL,ZWasCC : _
  1721.               NEXT
  1722.       END SUB
  1723. 1482 ' $SUBTITLE: 'QuickLPrnt - subroutine to quickly write to display'
  1724. ' $PAGE
  1725. '
  1726. '  NAME    -- QuickLPrnt
  1727. '
  1728. '  INPUTS  -- PARAMETER             MEANING
  1729. '             Strng$        STRING TO WRITE OUT
  1730. '             Num           NUMBER OF CARRIAGE RETURNS
  1731. '
  1732. '  OUTPUTS -- NONE
  1733. '
  1734. '  PURPOSE -- Subroutine to quickly write to the display.
  1735. '             Overwrites, and puts up count
  1736.       SUB QuickLPrnt (Strng$,Num) STATIC
  1737.       IF ZSnoop THEN _
  1738.          LOCATE ,1,1 : _
  1739.          CALL Pscrn (Strng$ + STR$(Num))
  1740.       END SUB
  1741. 1483 ' $SUBTITLE: 'PScrn    - subroutine to print to the screen'
  1742. ' $PAGE
  1743. '
  1744. '  NAME    -- PScrn
  1745. '
  1746. '  INPUTS  -- PARAMETER             MEANING
  1747. '             Strng$        STRING TO WRITE OUT
  1748. '
  1749. '  OUTPUTS -- NONE
  1750. '
  1751. '  PURPOSE -- Writes to local screen regardless of whether you have
  1752. '             carrier.  Assumes have positioned cursor where you want.
  1753. '
  1754.       SUB PScrn (Strng$) STATIC
  1755.       IF Strng$ = "" THEN _
  1756.          EXIT SUB
  1757.       IF ZUseBASICWrites THEN _
  1758.          PRINT Strng$; _
  1759.       ELSE CALL ANSI (Strng$,ZWasCL,ZWasCC) : _
  1760.            LOCATE ZWasCL,ZWasCC
  1761.       END SUB
  1762. 1485 ' $SUBTITLE: 'SkipLine - sub to write a blank line to user'
  1763. ' $PAGE
  1764. '
  1765. '  NAME    -- SkipLine
  1766. '
  1767. '  INPUTS  --   PARAMETER             MEANING
  1768. '               ZLocalUser
  1769. '               ZModemStatusReg
  1770. '               NumReturns
  1771. '               ZReturnLineFeed$
  1772. '               ZSnoop
  1773. '
  1774. '  OUTPUTS -- NONE
  1775. '
  1776. '  PURPOSE -- Skip lines on the user's terminal
  1777. '
  1778.       SUB SkipLine (NumReturns) STATIC
  1779.       FOR WasI=1 TO NumReturns
  1780.           CALL PutCom (ZReturnLineFeed$)
  1781.       NEXT
  1782.       IF NOT ZSnoop THEN _
  1783.          GOTO 1486
  1784.       IF ZUseBASICWrites THEN _
  1785.          FOR WasI = 1 TO NumReturns : _
  1786.             PRINT : _
  1787.          NEXT _
  1788.       ELSE FOR WasI = 1 TO NumReturns : _
  1789.               LOCATE ,,1 : _
  1790.               CALL ANSI(ZCrLf$,ZWasCL,ZWasCC) : _
  1791.               LOCATE ZWasCL,ZWasCC : _
  1792.            NEXT
  1793. 1486  ZLinesPrinted = ZLinesPrinted + NumReturns
  1794.       ZUnitCount = ZUnitCount - ZDisplayAsUnit * NumReturns
  1795.       END SUB
  1796. 1496 ' $SUBTITLE: 'SetCrLf -- sub to set up nulls/lf's for output'
  1797. ' $PAGE
  1798. '
  1799. '  NAME    -- SetCrLf
  1800. '
  1801. '  INPUTS  --   PARAMETER          MEANING
  1802. '              ZCarriageReturn$    CARRIAGE RETURN CHARACTER
  1803. '              ZLineFeed$          LINE FEED CHARACTER
  1804. '              ZLineFeeds          LINE FEED Switch
  1805. '              ZNul$                NULL CHARACTER
  1806. '
  1807. '  OUTPUTS -- ZReturnLineFeed$   END-OF-LINE STRING
  1808. '
  1809. '  PURPOSE -- Set up the necessary nulls/line feeds to end
  1810. '             each output to the communications port with.
  1811. '
  1812.       SUB SetCrLf STATIC
  1813.       ZReturnLineFeed$ = _
  1814.          MID$(ZCarriageReturn$,1, - (NOT ZLocalUser)) + _
  1815.          ZNul$ + _
  1816.          MID$(ZLineFeed$,1, - (ZLineFeeds <> 0))
  1817.       END SUB
  1818. 1498 ' $SUBTITLE: 'TGet -- ask a user a question and get reply'
  1819. ' $PAGE
  1820. '
  1821. '  NAME    -- TGet
  1822. '
  1823. '  INPUTS  --    PARAMETER                   MEANING
  1824. '                ZSubParm          = 1  STANDARD ENTRY
  1825. '                                  = 2  ENTRY AFTER A FUNCTION KEY
  1826. '                                         HAS BEEN HANDLED
  1827. '                                  = 3  ENTRY AFTER STACKED COMMAND
  1828. '             ZOutTxt$                        STRING TO WRITE TO THE
  1829. '                                       COMMUNICATIONS PORT
  1830. '             ZHidden                    IF THIS IS TRUE THEN ECHO
  1831. '                                       '.' INSTEAD OF ACTUAL
  1832. '                                       CHARACTER ENTERED.
  1833. '             ZForceKeyboard            IF TRUE, STACKED INPUT
  1834. '                                       IS BYPASSED AND KEYBOARD
  1835. '                                       INPUT IS READ.
  1836. '
  1837. '  OUTPUTS -- ZSubParm = -1 Carrier HAS BEEN DROPPED
  1838. '             ZUserIn$                  STRING THAT WAS ENTERED
  1839. '             ZWasQ                     NUMBER OF PARAMETERES THAT
  1840. '                                       WERE ENTERED WHICH WHERE
  1841. '                                       SEPARATED BY A SEMICOLON
  1842. '             ZUserIn$()                STRING MATRIX WITH EACH
  1843. '                                       ITEM CONTAIN THE STRING
  1844. '                                       THAT WAS ENTERED BETWEEN
  1845. '                                       SEMICOLONS.
  1846. '             ZFunctionKey        <>  0 FUNCTION KEY PRESSED
  1847. '             ZYes                      Reply IS "Y" OR "YES"
  1848. '             ZNo                       Reply IS "N" OR "NO"
  1849. '             ZNonStop                  Reply IS "NS" OR "ns"
  1850. '             ZKillMessage              Reply IS "K"
  1851. '             ZReply                    Reply IS "RE"
  1852. '
  1853. '  SUBROUTINE PURPOSE --  COMMON ROUTINE TO ASK A USER A QUESTION
  1854. '
  1855.      SUB TGet STATIC
  1856.      MacroIndex = ZForceKeyboard
  1857.      ON ZSubParm GOTO 1500,1538,1625
  1858. '
  1859. '
  1860. ' *  COMMON INPUT ROUTINE
  1861. '
  1862. '
  1863. 1500 CALL Carrier
  1864.      IF ZSubParm = -1 THEN _
  1865.         EXIT SUB
  1866.      ZLinesPrinted = 0
  1867.      ZDisplayAsUnit = ZFalse
  1868.      InStack = ZFalse
  1869.      GOSUB 1580
  1870.      ZWasA = 0
  1871.      ZWasB = 0
  1872.      ZWasC = 0
  1873.      ZWasQ = 1
  1874.      ZStoreParseAt = 1
  1875.      Parm = 0
  1876.      ZYes = ZFalse
  1877.      ZUserIn$ = ""
  1878.      SleepWarn = ZTrue
  1879.      ZNo = ZFalse
  1880.      ZNonStop = (ZPageLength < 1)
  1881.      IF ZOutTxt$ = "" THEN _
  1882.         GOTO 1525
  1883.      IF ZHidden THEN _
  1884.         ZOutTxt$ = ZOutTxt$ + " (dots echo)"
  1885.      IF (NOT ZVerifying) OR HoldA$ = "" THEN _
  1886.         CALL ColorPrompt (ZOutTxt$) : _
  1887.         ZOutTxt$ = ZOutTxt$ + _
  1888.              MID$("? !  ",2*ZTurboKey+1,2) : _
  1889.         HoldA$ = ZOutTxt$ _
  1890.      ELSE ZOutTxt$ = HoldA$
  1891.      ZSubParm = 4
  1892.      StopSave = ZStopInterrupts
  1893.      ZStopInterrupts = ZTrue
  1894.      CALL TPut
  1895.      ZStopInterrupts = StopSave
  1896.      IF ZSubParm = -1 OR ZFunctionKey <> 0 THEN _
  1897.         EXIT SUB
  1898. 1523 IF ZPromptBell THEN _
  1899.         IF ZLocalUser THEN _
  1900.            BEEP_
  1901.         ELSE CALL PutCom(ZBellRinger$)
  1902. 1525 CALL Carrier
  1903.      IF ZSubParm = -1 THEN _
  1904.         EXIT SUB
  1905.      IF LEN(ZCommPortStack$) > 0 THEN _
  1906.         InStack = ZTrue : _
  1907.         WasX = INSTR(ZCommPortStack$,ZCarriageReturn$) : _
  1908.         IF WasX > 0 THEN _
  1909.            ZOutTxt$ = LEFT$(ZCommPortStack$,WasX-1) : _
  1910.            ZCommPortStack$ = RIGHT$(ZCommPortStack$,LEN(ZCommPortStack$)-WasX) : _
  1911.            GOTO 1534 _
  1912.         ELSE ZWasY$ = LEFT$(ZCommPortStack$,1) : _
  1913.              ZCommPortStack$ = RIGHT$(ZCommPortStack$,LEN(ZCommPortStack$)-1) : _
  1914.              GOTO 1541
  1915.      IF (ZForceKeyboard OR (NOT ZMacroActive) OR (ZMacroSave > 0)) THEN _
  1916.         GOTO 1536
  1917. '
  1918. ' *** MACRO PROCESSING
  1919. '
  1920. 1526 CALL ReadMacro
  1921.      IF ZMacroSave > 0 THEN _
  1922.         GOTO 1500
  1923.      IF NOT ZMacroActive THEN _
  1924.         ZWasQ = 0 : _
  1925.         ZLastIndex = 0 : _
  1926.         EXIT SUB
  1927.      IF (ZDistantTGet > 0 ) OR (ZMacroTemplate$ <> "") THEN _
  1928.         GOTO 1536
  1929. 1534 ZUserIn$ = ZOutTxt$   ' Not Macro command - pass to normal processing
  1930.      IF ZMacroEcho THEN _
  1931.         ZSubParm = 4 : _
  1932.         CALL TPut
  1933.      WasX$ = ZCarriageReturn$
  1934.      GOTO 1547
  1935. 1536 IF ZLocalUser THEN _
  1936.         GOTO 1537
  1937.      '  CALL FindFKey: _
  1938.      '  IF ZSubParm < 0 THEN _
  1939.      '     EXIT SUB _
  1940.      '  ELSE GOTO 1538
  1941.      CALL EofComm (Char)
  1942.      IF Char <> -1 THEN _
  1943.         CALL GetCom(ZWasY$) : _
  1944.         IF ZSubParm = -1 THEN _
  1945.            EXIT SUB _
  1946.         ELSE GOTO 1541
  1947. 1537 CALL CheckTime(ZAutoLogoff!, TempElapsed!, 3)
  1948.      IF TempElapsed! < 30 THEN _
  1949.         IF TempElapsed! <= 0 THEN _
  1950.            CALL UpdtCalr ("Sleep disconnect",1) : _
  1951.            ZSubParm = -1 : _
  1952.            ZNo = ZTrue : _
  1953.            ZSleepDisconnect = ZTrue : _
  1954.            EXIT SUB _
  1955.         ELSE IF SleepWarn THEN _
  1956.                 SleepWarn = ZFalse : _
  1957.                 ZOutTxt$ = "LOGGING you OFF if you do not respond in 30 seconds!" : _
  1958.                 CALL RingCaller
  1959.      CALL FindFKey
  1960.      IF ZSubParm < 0 THEN _
  1961.         EXIT SUB
  1962. 1538 ZWasY$ = ZKeyPressed$
  1963.      IF ZWasY$ <> "" THEN _
  1964.         GOTO 1545
  1965.      SendRemote = ZTrue
  1966.      CALL GoIdle
  1967.      GOTO 1525
  1968. 1541 SendRemote = ZRemoteEcho
  1969.      IF ZTestParity THEN _
  1970.         GOTO 1542
  1971.      IF ZWasY$ = CHR$(127) THEN _
  1972.         GOTO 1635
  1973.      GOTO 1545
  1974. 1542 IF ZWasY$ = "" THEN _
  1975.         ZWasY$ = " "
  1976.      IF ASC(ZWasY$) = 141 THEN _
  1977.         OUT ZLineCntlReg,&H1A : _
  1978.         ZEightBit = ZFalse : _
  1979.         ZTestParity = ZFalse : _
  1980.         ZWasGR = ZFalse
  1981.      ZWasY$ = CHR$(ASC(ZWasY$) AND 127)
  1982. 1545 WasX$ = ZWasY$
  1983.      IF INSTR(ZLineEditChk$,ZWasY$) > 5 _
  1984.         GOTO 1635
  1985.      IF ZWasY$ < " " AND ZWasY$ <> ZCarriageReturn$ THEN _
  1986.         GOTO 1525
  1987.      IF ZWasY$ = "^" THEN _
  1988.         GOTO 1525
  1989.      IF ZWasY$ = ZCarriageReturn$ THEN _
  1990.         GOTO 1547 _
  1991.      ELSE GOSUB 1550
  1992.      IF ZTurboKey < 1 THEN _
  1993.         GOTO 1546
  1994.      IF ZWasY$ = " " THEN _
  1995.         ZWasY$ = ""
  1996.      IF ZWasY$ <> "/" THEN _
  1997.         ZUserIn$ = ZWasY$ : _
  1998.         ZWasY$ = ZCarriageReturn$ : _
  1999.         WasX$ = ZWasY$ : _
  2000.         GOTO 1547
  2001.      ZTurboKey = 0
  2002.      GOTO 1525
  2003. 1546 IF LEN(ZUserIn$) => 512 THEN _
  2004.         ZOutTxt$ = "Input too long!" : _
  2005.         ZSubParm = 5 : _
  2006.         CALL TPut : _
  2007.         IF ZSubParm = -1 OR ZFunctionKey <> 0 THEN _
  2008.            EXIT SUB _
  2009.         ELSE GOTO 1500
  2010.      ZUserIn$ = ZUserIn$ + _
  2011.           ZWasY$
  2012.      GOTO 1525
  2013. 1547 ZTurboKey = ZFalse          ' Carriage Return Handler
  2014.      ZHidden = ZFalse
  2015.      IF ZNoAdvance THEN _
  2016.         ZNoAdvance = ZFalse : _
  2017.         GOTO 1575 _
  2018.      ELSE CALL LPrnt (ZCrLf$,0) : _
  2019.           GOSUB 1551 : _
  2020.           GOTO 1570
  2021. 1550 IF ZLogonActive THEN _
  2022.         IF (ZWasY$ = " " OR ZWasY$ = ";") AND _
  2023.            RIGHT$(ZUserIn$,1) <> " " AND RIGHT$(ZUserIn$,1) <> ";" THEN _
  2024.               Parm = Parm + 1 : _
  2025.               ZLogonActive = (Parm < 3) : _
  2026.               ZHidden = (Parm = 2) : _
  2027.               CALL LPrnt(WasX$,0) : _
  2028.               GOTO 1551
  2029.      IF ZHidden AND (WasX$ <> " ") THEN _
  2030.         WasX$ = "."
  2031.      CALL LPrnt(WasX$,0)
  2032. 1551 IF NOT SendRemote THEN _
  2033.         RETURN
  2034.      IF ZHidden AND (WasX$ <> " ") THEN _
  2035.         WasX$ = "."
  2036. 1553 CALL PutCom (WasX$)
  2037.      RETURN
  2038. 1570 IF SendRemote THEN _
  2039.         IF ZLineFeeds THEN _
  2040.            CALL PutCom (ZLineFeed$)
  2041. 1575 IF LEN(ZUserIn$) > 4000 THEN _
  2042.         ZOutTxt$ = "Try again, " + _
  2043.              ZFirstName$ : _
  2044.         ZSubParm = 5 : _
  2045.         CALL TPut : _
  2046.         IF ZSubParm = -1 OR ZFunctionKey <> 0 THEN _
  2047.            EXIT SUB _
  2048.         ELSE GOTO 1500
  2049.      IF ZParseOff THEN _
  2050.         ZParseOff = ZFalse : _
  2051.         GOTO 1620
  2052.      CALL ParseIt
  2053.      IF ZWasQ = 1 THEN _
  2054.         GOTO 1622
  2055.      GOTO 1625
  2056. 1580 ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  2057.      RETURN
  2058. 1620 ZUserIn$(ZStoreParseAt) = ZUserIn$
  2059.      ZWasQ = 1
  2060. 1622 IF ZUserIn$ = "" THEN _
  2061.         ZWasQ = 0 : _
  2062.         ZHidden = ZFalse : _
  2063.         GOTO 1628
  2064. 1625 IF LEN(ZUserIn$) < 4 THEN _
  2065.         WasX$ = LEFT$(ZUserIn$,3): _
  2066.         CALL AllCaps (WasX$) : _
  2067.         IF WasX$ = "Y" OR WasX$ = "YES" THEN _
  2068.            ZYes = ZTrue _
  2069.         ELSE IF WasX$ = "N" OR WasX$ = "NO" OR WasX$ = "A" THEN _
  2070.                 ZNo = ZTrue _
  2071.              ELSE IF WasX$ = "RE" THEN _
  2072.                      ZReply = ZTrue : _
  2073.                      GOTO 1628 _
  2074.                   ELSE IF WasX$ = "K" THEN _
  2075.                           ZKillMessage = ZTrue : _
  2076.                           GOTO 1628
  2077.      ZHidden = ZFalse
  2078. 1628 CALL VerifyAns
  2079.      IF NOT ZOK THEN _
  2080.         CALL QuickTPut1 ("Invalid answer <" + ZUserIn$(1) + ">") : _
  2081.         GOTO 1500
  2082.      HoldA$ = ""
  2083.      ZForceKeyboard = ZFalse
  2084.      IF ZMacroSave > 0 THEN _
  2085.         ZGSRAra$(ZMacroSave) = ZUserIn$ : _
  2086.         ZMacroSave = 0 : _
  2087.         GOTO 1632
  2088.      IF (ZDistantTGet > 0) OR (ZMacroTemplate$ <> "") THEN _
  2089.         CALL WipeLine (38) : _
  2090.         IF NOT ZNo THEN _
  2091.            GOTO 1632 _
  2092.         ELSE ZWasQ = 0 : _
  2093.              ZMacroTemplate$ = "" : _
  2094.              ZDistantTGet = 0 : _
  2095.              ZNo = ZFalse : _
  2096.              GOTO 1633
  2097.      IF ZMacroActive THEN _
  2098.         ZLastIndex = ZWasQ : _
  2099.         FirstIndex = 1: _
  2100.         EXIT SUB
  2101.      IF ZAnsIndex > 255 OR ((NOT InStack) AND INSTR(ZUserIn$,".") > 0) THEN _
  2102.         EXIT SUB
  2103.      IF MacroIndex THEN _
  2104.         MacroIndex = 1 _
  2105.      ELSE MacroIndex = ZAnsIndex
  2106.      CALL NoPath (ZUserIn$(MacroIndex),Found)
  2107.      IF Found THEN _
  2108.         EXIT SUB
  2109.      CALL CheckMacro (ZUserIn$(MacroIndex),Found)
  2110.      IF Found THEN _
  2111.         ZStoreParseAt = ZAnsIndex : _
  2112.         GOTO 1525
  2113.      EXIT SUB
  2114. 1632 ZUserIn$ = ""
  2115.      ZForceKeyboard = ZFalse
  2116. 1633 GOSUB 1580
  2117.      ZWasQ = 1
  2118.      GOTO 1525
  2119. 1635 IF LEN(ZUserIn$) = 0 THEN _
  2120.         GOTO 1525
  2121.      IF ZLogonActive THEN _
  2122.         IF INSTR(" ;",RIGHT$(ZUserIn$,1)) > 0 THEN _
  2123.            Parm = Parm - 1
  2124.      ZUserIn$ = LEFT$(ZUserIn$,LEN(ZUserIn$)-1)
  2125.      CALL LPrnt(ZLocalBksp$,0)
  2126.      IF SendRemote THEN _
  2127.         CALL PutCom(ZBackSpace$)
  2128.      GOTO 1525
  2129.      END SUB
  2130. 1636 ' $SUBTITLE: 'RingCaller - sub to use sound + screen emphasis'
  2131. ' $PAGE
  2132. '
  2133. '  NAME    -- RingCaller
  2134. '
  2135. '  INPUTS  --     PARAMETER                    MEANING
  2136. '                 ZOutTxt$                           STRING TO EMPHASIZE
  2137. '
  2138. '  OUTPUTS --  none
  2139. '
  2140. '  PURPOSE --  Rings the users bell before and after string
  2141. '              (but not snooping sysop) and adds emphasis around
  2142. '              message sent.
  2143. '
  2144.      SUB RingCaller STATIC
  2145.      WasX$ = LEFT$(ZBellRinger$,-ZLocalUser)
  2146.      CALL PutCom (ZBellRinger$)
  2147.      CALL LPrnt (WasX$,0)
  2148.      ZSubParm = 2
  2149.      ZOutTxt$ = ZEmphasizeOn$ + ZOutTxt$ + ZEmphasizeOff$
  2150.      CALL TPut
  2151.      CALL PutCom (ZBellRinger$)
  2152.      CALL LPrnt (WasX$,0)
  2153.      END SUB
  2154. 1637 ' $SUBTITLE: 'ParseIt - subroutine to parse a string'
  2155. ' $PAGE
  2156. '
  2157. '  NAME    -- ParseIt
  2158. '
  2159. '  INPUTS  --     PARAMETER                    MEANING
  2160. '                 ZUserIn$                     STRING TO PARSE
  2161. '
  2162. '  OUTPUTS --  ZWasQ                           NUMBER PARSED
  2163. '              ZUserIn$()                      PARSED STRINGS
  2164. '
  2165. '  PURPOSE --  To parse a string into pieces.  Uses semicolon
  2166. '              if exists, otherwise space, otherwise comma
  2167. '
  2168.      SUB ParseIt STATIC
  2169.      ZWasA = INSTR(ZUserIn$,";")
  2170.      IF ZWasA > 0 THEN _
  2171.         ParseChar$ = ";" _
  2172.      ELSE IF ZUserIn$ <> SPACE$(LEN(ZUserIn$)) THEN _
  2173.              CALL Trim (ZUserIn$) : _
  2174.              WasX$ = ZUserIn$ : _
  2175.              ZWasA = INSTR(ZUserIn$,"  ") : _
  2176.              WHILE ZWasA > 0 : _
  2177.                 ZUserIn$ = LEFT$(ZUserIn$,ZWasA - 1) + _
  2178.                      MID$(ZUserIn$,ZWasA + 1) : _
  2179.                 ZWasA = INSTR(ZWasA,ZUserIn$,"  ") : _
  2180.              WEND : _
  2181.              ZWasA = INSTR(ZUserIn$," ") : _
  2182.              IF ZWasA > 1 THEN _
  2183.                 ParseChar$ = " " _
  2184.              ELSE ZWasA = INSTR(ZUserIn$,",") : _
  2185.                   ParseChar$ = ","
  2186.      IF ZWasA > 1 THEN _
  2187.         GOTO 1639
  2188.      ZWasDF$ = ZUserIn$
  2189.      CALL AllCaps (ZWasDF$)
  2190.      IF ZWasDF$ = "NS" THEN _
  2191.          ZUserIn$ = "C" : _
  2192.          ZNonStop = ZTrue
  2193.      ZUserIn$(ZStoreParseAt) = ZUserIn$
  2194.      ZNonStop = ZNonStop OR (ZWasDF$ = "C" AND NOT ZStackC)
  2195.      GOTO 1642
  2196. 1639 ZUserIn$(ZStoreParseAt) = LEFT$(ZUserIn$,ZWasA - 1)
  2197.      ZWasA = ZWasA + 1
  2198.      ZEOL = ZFalse
  2199. 1640 ZWasB = INSTR(ZWasA,ZUserIn$,ParseChar$)
  2200.      ZWasC = ZWasB-ZWasA
  2201.      IF ZWasC < 1 THEN _
  2202.         ZEOL = ZTrue : _
  2203.         ZWasC = 128
  2204.      ZWasDF$ = MID$(ZUserIn$,ZWasA,ZWasC)
  2205.      IF ZWasDF$ <> "" THEN _
  2206.         ZWasQ = ZWasQ + 1 : _
  2207.         ZStoreParseAt = ZStoreParseAt + 1 : _
  2208.         ZUserIn$(ZStoreParseAt) = ZWasDF$ : _
  2209.         CALL AllCaps(ZWasDF$) : _
  2210.         WasX = INSTR(";NS;/G;C;",";"+ZWasDF$+";") : _
  2211.         IF WasX > 0 THEN _
  2212.            ZNonStop = ZNonStop OR (WasX = 1) OR (WasX = 7 AND NOT ZStackC) : _
  2213.            ZAutoLogoffReq = ZAutoLogoffReq OR (WasX = 4) : _
  2214.            IF ZWasQ > 0 AND WasX < 7 THEN _
  2215.               ZWasQ = ZWasQ - 1 : _
  2216.               ZStoreParseAt = ZStoreParseAt - 1
  2217.      IF NOT ZEOL AND ZWasQ < 50 THEN _
  2218.         ZWasA = ZWasB + 1 : _
  2219.         GOTO 1640
  2220.      IF ParseChar$ <> ";" THEN _
  2221.         ZUserIn$ = WasX$
  2222. 1642 ZStackC = ZFalse
  2223.      END SUB
  2224. 1650 ' $SUBTITLE: 'PopCmdStack - prompt for value with command stack check'
  2225.      SUB PopCmdStack STATIC
  2226.      CALL CheckCarrier
  2227.      IF ZSubParm = -1 THEN _
  2228.         ZLastIndex = 0 : _
  2229.         ZWasQ = 0 : _
  2230.         EXIT SUB
  2231.      ZWasQ = 1
  2232. 1651 IF ZAnsIndex < ZLastIndex THEN _
  2233.         ZAnsIndex = ZAnsIndex + 1 : _
  2234.         ZUserIn$ = ZUserIn$(ZAnsIndex) : _
  2235.         IF (NOT ZStackC) AND ZAnsIndex > 1 AND INSTR("Cc",ZUserIn$) > 0 AND LEN(ZUserIn$) = 1 THEN _
  2236.            GOTO 1651 _
  2237.         ELSE ZSubParm = 3 : _
  2238.              CALL TGet : _
  2239.              GOTO 1652
  2240.      ZLastIndex = 0
  2241.      ZAnsIndex = 1
  2242.      ZSubParm = 1
  2243.      ZSearchingAll = ZFalse
  2244.      CALL TGet
  2245.      ZLastIndex = ZWasQ
  2246. 1652 IF ZStoreParseAt > ZLastIndex THEN _
  2247.         IF ZLastIndex > 0 THEN _
  2248.            ZLastIndex = ZStoreParseAt
  2249.      ZStackC = ZFalse
  2250.      ZParseOff = ZFalse
  2251.      END SUB
  2252. 1654 ' $SUBTITLE: 'SetBaud - sub to set the baud rate in the RS232'
  2253. ' $PAGE
  2254. '
  2255. '  NAME    -- SetBaud
  2256. '
  2257. '  INPUTS  --     PARAMETER                    MEANING
  2258. '             ZBaudRateDivisor   NUMBER TO DIVIDE THE 8250 CHIP'S
  2259. '                                 PROGRAMABLE CLOCK TO ADJUST THE
  2260. '                                 BAUD RATE TO THE USER'S BAUD
  2261. '                                 RATE (INDEPENDENT OF THE BAUD
  2262. '                                 RATE USED TO OPEN THE COMM. PORT)
  2263. '
  2264. '        DESIRED BAUD        DIVISIOR (DECIMAL) TO OBTAIN DESIRED BAUD RATE
  2265. '            RATE              PCjr         PC AND XT
  2266. '              50             2237             2304
  2267. '              75             1491             1536
  2268. '             110             1017             1047
  2269. '             134.5            832              857
  2270. '             150              746              768
  2271. '             300              373              384
  2272. '             600              186              192
  2273. '            1200               93               96
  2274. '            1800               62               64
  2275. '            2000               56               58
  2276. '            2400               47               48
  2277. '            3600               31               32
  2278. '            4800               23               24
  2279. '            7200          not available         16
  2280. '            9600          not available         12
  2281. '           19200          not available          6
  2282. '           38400               "                 3
  2283. '  OUTPUTS -- BAUD RATE SET IN THE RS232 INTERFACE
  2284. '
  2285. '  PURPOSE -- To set the baud rate in the RS232 interface
  2286. '             inpependent of the baud rate the communications port
  2287. '             was opened at
  2288. '
  2289.       SUB SetBaud STATIC
  2290.      IF NOT ZKeepInitBaud THEN _
  2291.         ZTalkToModemAt$ =  MID$(ZBaudRates$,(-5 * ZBPS),5) _
  2292.      ELSE ZTalkToModemAt$ = ZModemInitBaud$
  2293.      CALL Trim (ZTalkToModemAt$)
  2294.      IF LEN(ZTalkToModemAt$) < 5 THEN _
  2295.         ZTalkToModemAt$ = SPACE$(4 - LEN(ZTalkToModemAt$)) + _
  2296.                             ZTalkToModemAt$
  2297.      IF ZEightBit THEN_
  2298.         Parity = 2 : _                                    ' No PARITY
  2299.         DataBits = 3 : _                                  ' 8 DATA BITS
  2300.         StopBits = 0 _                                    ' 1 STOP BIT
  2301.      ELSE Parity = 3 : _                                  ' EVEN PARITY
  2302.           DataBits = 2 : _                                ' 7 DATA BITS
  2303.           StopBits = 0                                    ' 1 STOP BIT
  2304.      ComSpeed! = VAL(ZTalkToModemAt$)
  2305.      IF ComSpeed! > 19200 THEN _
  2306.         IF FOSSIL THEN _
  2307.            WasI = &H9600 _
  2308.         ELSE WasI = 19200 _
  2309.      ELSE WasI = ComSpeed!
  2310.      IF ZFossil THEN _
  2311.         CALL FosSpeed(ZComPort,WasI,Parity,DataBits,StopBits) : _
  2312.         EXIT SUB
  2313.      IF ComSpeed! = 2400 THEN _
  2314.         ZBaudRateDivisor = &H30 + (1 * (ZComputerType = 2)) _
  2315.      ELSE IF ComSpeed! = 1200 THEN _
  2316.         ZBaudRateDivisor = &H60 + (3 * (ZComputerType = 2)) _
  2317.      ELSE IF ComSpeed! = 9600 THEN _
  2318.         ZBaudRateDivisor = &HC _
  2319.      ELSE IF ComSpeed! = 300 THEN _
  2320.         ZBaudRateDivisor = &H180 + (11 * (ZComputerType = 2)) _
  2321.      ELSE IF ComSpeed! = 450 THEN _
  2322.         ZBaudRateDivisor = &H100 + (8 * (ZComputerType = 2)) _
  2323.      ELSE IF ComSpeed! = 4800 THEN _
  2324.         ZBaudRateDivisor = &H18 _
  2325.      ELSE IF ComSpeed! = 19200 THEN _
  2326.         ZBaudRateDivisor = &H6 _
  2327.      ELSE IF ComSpeed! = 38400 THEN _
  2328.         ZBaudRateDivisor = &H3
  2329.      MostSignifByte = FIX (ZBaudRateDivisor / 256)
  2330.      LeastSignifByte = ZBaudRateDivisor - (MostSignifByte * 256)
  2331.      LineCntlStatus = INP(ZLineCntlReg)
  2332.      MSBSave = INP(ZMSB)
  2333.      OUT ZMSB,0
  2334.      OUT ZLineCntlReg,LineCntlStatus OR 128
  2335.      OUT ZLSB,LeastSignifByte
  2336.      OUT ZMSB,MostSignifByte
  2337.      OUT ZLineCntlReg,LineCntlStatus
  2338.      OUT ZMSB,MSBSave
  2339.      END SUB
  2340. 2018 ' $SUBTITLE: 'MessageTo - subroutine to get who a message is to'
  2341. ' $PAGE
  2342. '
  2343. '  NAME    -- MessageTo
  2344. '
  2345. '  INPUTS  --     PARAMETER                    MEANING
  2346. '              HighestUserRecord
  2347. '
  2348. '  OUTPUTS --  MsgTo$              Who message is to
  2349. '              RcvrRecNum         User record # of who to
  2350. '
  2351. '  PURPOSE --  Asks who a message is to and determines if receiver exists
  2352. '
  2353.      SUB MessageTo (HighestUserRecord,MsgTo$,MsgFrom$,RcvrRecNum,Found) STATIC
  2354.      Temp$ = MsgFrom$
  2355.      CALL Trim (Temp$)
  2356. 2020 IF MsgTo$ <> "" THEN _
  2357.         GOTO 2032
  2358.      ZOutTxt$ = "To [A]ll,S)ysop, or name"
  2359.      CALL SkipLine (1)
  2360.      ZParseOff = ZTrue
  2361.      GOSUB 2033
  2362.      IF LEN(ZUserIn$) > 30 THEN _
  2363.         CALL QuickTPut1 ("30 Char. Max") : _
  2364.         GOTO 2020
  2365. 2030 Found = ZTrue
  2366.      RcvrRecNum = 0
  2367.      IF ZWasQ = 0 THEN _
  2368.         MsgTo$ = "ALL" _
  2369.      ELSE CALL AllCaps (ZUserIn$) : _
  2370.           IF ZUserIn$ = "A" THEN _
  2371.              MsgTo$ = "ALL" : _
  2372.              EXIT SUB _
  2373.           ELSE IF ZUserIn$ = "S" THEN _
  2374.              MsgTo$ = "SYSOP" _
  2375.           ELSE MsgTo$ = ZUserIn$
  2376. 2032 IF MsgTo$ <> "ALL" THEN _
  2377.         IF (LEFT$(MsgTo$,4) <> "ALL " AND ZStartHash = 1) THEN _
  2378.            TempHashValue$ = MsgTo$ : _
  2379.            CALL WhoCheck (TempHashValue$,Found,RcvrRecNum) : _
  2380.            IF NOT Found THEN _
  2381.               ZLastIndex = 0 : _
  2382.               IF NOT ZReply THEN _
  2383.                  ZOutTxt$ = "[R]e-enter name, Q)uit, C)ontinue" : _
  2384.                  ZTurboKey = -ZTurboKeyUser : _
  2385.                  ZLastIndex = 0 : _
  2386.                  GOSUB 2033 : _
  2387.                  ZWasZ$ = ZUserIn$(1) : _
  2388.                  CALL AllCaps (ZWasZ$) : _
  2389.                  IF ZWasZ$ <> "C" THEN _
  2390.                     MsgTo$ = "" : _
  2391.                     IF ZWasZ$ <> "Q" THEN _
  2392.                        GOTO 2020
  2393.      IF MsgTo$ = Temp$ THEN _
  2394.         ZOutTxt$ = "Msg would be from and to SAME PERSON!  Really do this (Y,[N])" : _
  2395.         ZLastIndex = 0 : _
  2396.         GOSUB 2033 : _
  2397.         IF NOT ZYes THEN _
  2398.            MsgTo$ = ""
  2399.      EXIT SUB
  2400. 2033 CALL PopCmdStack
  2401.      IF ZSubParm < 0 THEN _
  2402.         EXIT SUB
  2403.      RETURN
  2404.      END SUB
  2405. 2055 ' $SUBTITLE: 'MsgProt - gets protection wanted for a message'
  2406. ' $PAGE
  2407. '
  2408. '  NAME    -- MsgProt
  2409. '
  2410. '  INPUTS  --     PARAMETER                    MEANING
  2411. '                 MsgTo$
  2412. '                 Found
  2413. '
  2414. '  OUTPUTS --  ZPswd$                Protection desired
  2415. '
  2416. '  PURPOSE --  Sets protection desired for a new message
  2417. '
  2418.      SUB MsgProt (MsgTo$,Found,MsgPswd$) STATIC
  2419.      IF MsgTo$ = "ALL" THEN _
  2420.         GOTO 2090
  2421. 2060 ZOutTxt$ = "Make message p(U)blic, p(R)ivate, (P)assword protected, (H)elp"
  2422.      IF MsgPswd$ = "^READ^" THEN _
  2423.         DefaultProt$ = "R" : _
  2424.         GOTO 2065
  2425.      IF LEFT$(MsgPswd$,1) = "!" THEN _
  2426.         DefaultProt$ = "P" _
  2427.      ELSE _
  2428.         DefaultProt$ = "U"
  2429. 2065 MID$(ZOutTxt$,INSTR(ZOutTxt$,"("+DefaultProt$+")"),3) = "["+DefaultProt$+"]"
  2430.      ZTurboKey = -ZTurboKeyUser
  2431.      GOSUB 2096
  2432.      IF ZWasQ = 0 THEN _
  2433.         ZUserIn$(ZAnsIndex) = DefaultProt$
  2434.      ZWasZ$ = LEFT$(ZUserIn$(ZAnsIndex),1)
  2435.      CALL AllCaps (ZWasZ$)
  2436.      ON INSTR("RUPH",ZWasZ$) GOTO 2075,2090,2075,2070
  2437.      GOTO 2060
  2438. '
  2439. ' **  DISPLAY MESSAGE PROTECT HELP   *
  2440. '
  2441. 2070 CALL BufFile (ZHelp$(3),WasX)
  2442.      GOTO 2060
  2443. '
  2444. ' ** MAKE MESSAGE READ PROTECTED (ONLY ADDRESSEE AND SYSOP CAN READ IT) *
  2445. '
  2446. 2075 IF MsgTo$ = "ALL" THEN _
  2447.         CALL QuickTPut1 ("Msg to ALL cannot be private") : _
  2448.         GOTO 2060
  2449.      IF ZWasZ$ = "P" THEN _
  2450.         GOTO 2088
  2451. 2081 CALL QuickTPut1 ("Sending personal mail to " + MsgTo$)
  2452. 2084 MsgPswd$ = "^READ^"
  2453.      EXIT SUB
  2454. 2085 ZOutTxt$ = "Password"
  2455.      GOSUB 2096
  2456.      IF ZWasQ = 0 THEN _
  2457.         IF LEFT$(MsgPswd$,1) = "!" THEN _
  2458.            MsgPswd$ = MID$(MsgPswd$,2) : _
  2459.            CALL QuickTPut1 ("Password is " + MsgPswd$) : _
  2460.            RETURN _
  2461.         ELSE _
  2462.         GOTO 2085
  2463.      IF LEN(ZUserIn$) > WasL THEN _
  2464.         CALL QuickTPut1 (STR$(WasL) + " Chars. max") : _
  2465.         GOTO 2085
  2466.      IF WasL = 15 AND LEFT$(ZUserIn$,1) = "!" THEN _
  2467.         CALL QuickTPut1 ("Password can't begin with '!'") : _
  2468.         GOTO 2085
  2469.      RETURN
  2470. '
  2471. ' **  PASSWORD PROTECT MESSAGE (USERS WITH PASSWORD AND SYSOP CAN READ) *
  2472. '
  2473. 2088 ZOutTxt$ = "Receiver(s) Must KNOW PASSWORD TO READ msg.  Use password (Y/[N])"
  2474.      GOSUB 2093
  2475.      IF NOT ZYes THEN _
  2476.         GOTO 2070
  2477.      WasL = 14
  2478.      WasA1$ = "!"
  2479.      GOSUB 2085
  2480.      CALL AllCaps (ZUserIn$)
  2481.      GOTO 2092
  2482. '
  2483. ' ** MAKE MESSAGE KILL PROTECTED (ONLY SENDER, ADDRESSEE AND SYSOP CAN KILL) *
  2484. '
  2485. 2090 WasL = 15
  2486.      WasA1$ = ""
  2487.      ZUserIn$ = "^KILL^"
  2488. 2092 MsgPswd$ = WasA1$ + _
  2489.                          ZUserIn$
  2490.      EXIT SUB
  2491. 2093 ZTurboKey = -ZTurboKeyUser
  2492. 2094 ZSubParm = 1
  2493.      CALL TGet
  2494. 2095 IF ZSubParm = -1 THEN _
  2495.         EXIT SUB
  2496.      RETURN
  2497. 2096 CALL PopCmdStack
  2498.      GOTO 2095
  2499.      END SUB
  2500. 2250 ' $SUBTITLE: 'WhoCheck - Checks whether user exists'
  2501. ' $PAGE
  2502. '
  2503. '  NAME    -- WhoCheck
  2504. '
  2505. '  INPUTS  --   PARAMETER                    MEANING
  2506. '              WhoFind$                User to find
  2507. '
  2508. '  OUTPUTS --  WhoFound                Whether user found
  2509. '              UserNumFound           Record # of user
  2510. '
  2511. '  PURPOSE --  Validate that user record exists.  Sysop
  2512. '              counted as found even if lack user record.
  2513. '
  2514.      SUB WhoCheck (WhoFind$,WhoFound,UserNumFound) STATIC
  2515.      UserNumFound = 0
  2516.      IF ZStartHash <> 1 THEN _
  2517.         WhoFound = ZTrue : _
  2518.         EXIT SUB
  2519.      Work128$ = ZUserRecord$
  2520.      WhoFound = ZFalse
  2521.      ToSysop = (INSTR(WhoFind$,"SYSOP") > 0 OR _
  2522.                  INSTR(WhoFind$,ZSysopPswd1$ + " " + ZSysopPswd2$) > 0 )
  2523.      CALL OpenUser (HighestUserRecord)
  2524.      FIELD 5, 128 AS ZUserRecord$
  2525.      IF ToSysop THEN _
  2526.         WasX$ = ZSysopPswd1$ + " " + ZSysopPswd2$ _
  2527.      ELSE WasX$ = WhoFind$
  2528.      IF LEN(WasX$) > 1 THEN _
  2529.         CALL FindUser (WasX$,"",ZStartHash,ZLenHash,_
  2530.                        0,0,HighestUserRecord,WhoFound,_
  2531.                        UserNumFound,ZWasSL)
  2532.      LSET ZUserRecord$ = Work128$
  2533.      IF NOT WhoFound THEN _
  2534.         IF ToSysop THEN _
  2535.            WhoFound = ZTrue _
  2536.         ELSE CALL QuickTPut1 (WhoFind$ + " not active user")
  2537.      END SUB
  2538. 2618 ' $SUBTITLE: 'EditALine - Edits a line in a message'
  2539. ' $PAGE
  2540. '
  2541. '  NAME    -- EditALine
  2542. '
  2543. '  INPUTS  --     PARAMETER                    MEANING
  2544. '                 WasL                        Line # to edit
  2545. '
  2546. '  OUTPUTS --  ZOutTxt$(WasL)                 Edited line
  2547. '
  2548. '  PURPOSE --  Edit a line in a message.
  2549. '
  2550.      SUB EditALine (WasL) STATIC
  2551. 2620 ZOutTxt$ = "Line #" + _
  2552.           STR$(WasL) + _
  2553.           " is:" + _
  2554.           ZReturnLineFeed$ + _
  2555.           ZOutTxt$(WasL)
  2556.      ZSubParm = 3
  2557.      CALL TPut
  2558.      GOSUB 2695
  2559.      IF NOT ZExpertUser THEN _
  2560.         CALL QuickTPut1 ("Search & replace")
  2561.      ZOutTxt$ = "Search for" + _
  2562.           ZPressEnterExpert$
  2563.      ZMacroMin = 99
  2564.      ZParseOff = ZTrue
  2565.      ZSubParm = 1
  2566.      GOSUB 2694
  2567.      IF ZWasQ = 0 THEN _
  2568.         EXIT SUB
  2569.      ZWasY$ = LEFT$(ZUserIn$,1)
  2570.      IF ZWasY$ = RIGHT$(ZUserIn$,1) THEN _
  2571.         IF LEN(ZUserIn$) > 2 THEN _
  2572.            WasX = INSTR(2,ZUserIn$,ZWasY$) : _
  2573.            IF WasX < LEN(ZUserIn$) THEN _
  2574.               IF ZWasY$ < "0" OR (ZWasY$ > "9" AND ZWasY$ < "A") THEN _
  2575.                  ZUserIn$ = MID$(ZUserIn$,2,LEN(ZUserIn$)-2) : _
  2576.                  WasX = WasX - 1 : _
  2577.                  GOTO 2622
  2578.      WasX = INSTR(ZUserIn$,";")
  2579. 2622 IF WasX > 0 THEN _
  2580.         WasX$ = LEFT$(ZUserIn$,WasX-1) : _
  2581.         ZWasY$ = RIGHT$(ZUserIn$,LEN(ZUserIn$)-WasX) : _
  2582.         GOTO 2660
  2583.      WasX$ = ZUserIn$
  2584.      ZOutTxt$ = "And replace by"
  2585.      ZParseOff = ZTrue
  2586.      ZSubParm = 1
  2587.      GOSUB 2694
  2588.      ZWasY$ = ZUserIn$
  2589. 2660 WasX = INSTR(1,ZOutTxt$(WasL),WasX$)
  2590.      IF WasX = 0 THEN _
  2591.         CALL QuickTPut1 ("<" + WasX$ + "> not found in line" + STR$(WasL)) : _
  2592.         GOTO 2620
  2593. 2670 ZFF = LEN(WasX$)
  2594.      WasJJ = LEN(ZWasY$)
  2595.      IF ZFF = WasJJ THEN _
  2596.         MID$(ZOutTxt$(WasL),WasX) = ZWasY$ : _
  2597.         GOTO 2620
  2598. 2690 ZWasDF$ = LEFT$(ZOutTxt$(WasL),WasX - 1)
  2599.      ZOutTxt$(WasL) = ZWasDF$ + _
  2600.              ZWasY$ + _
  2601.              MID$(ZOutTxt$(WasL),WasX + ZFF)
  2602.      IF LEN(ZOutTxt$(WasL)) > ZRightMargin THEN _
  2603.         CALL WordWrap (ZRightMargin, ZLinesInMsg, ZOutTxt$())
  2604.      GOTO 2620
  2605. 2694 CALL TGet
  2606. 2695 IF ZSubParm > -1 THEN _
  2607.         RETURN
  2608.      END SUB
  2609.  
  2610. 3700 ' $SUBTITLE: 'LineEdit  - subroutine to produce edited line'
  2611. ' $PAGE
  2612. '
  2613. '  NAME    -- LineEdit
  2614. '
  2615. '  INPUTS  -- PARAMETER             MEANING
  2616. '             ZBackArrow$
  2617. '             ZBackSpace$
  2618. '             ZCarriageReturn$
  2619. '             ZLineFeed$
  2620. '             ZLineMes$          BUFFER SPACE TO USE FOR HOLDING LINE
  2621. '             ZLocalUser
  2622. '             MaxLen             MAXIMUM LENGTH OF STRING TO INPUT
  2623. '             MsgLine            WHERE IN ZOutTxt$() TO PUT THE EDITED LINE
  2624. '             ZRightMargin
  2625. '             ZSnoop
  2626. '             ZStopInterrupts
  2627. '             ZTabSize           TAB STOP EVERY x COLUMNS
  2628. '             ZWaitExpired
  2629. '
  2630. '  OUTPUTS -- ZOutTxt$(MsgLine)  EDITED LINE
  2631. '
  2632. '  PURPOSE -- Subroutine to edit a line quickly using a minimum of
  2633. '             string space.
  2634. '
  2635. ' -------------------------------------------------------------------------
  2636. ' Source has been totally rewriteen so as to be legible, and to support
  2637. ' both tabs and tab erasures.  This code has been written to conform
  2638. ' with MicroSoft QuickBASIC v4.5 specifications, and may not work with
  2639. ' QB 3.0 without modification.  Rewrite by Tim Gage 5/8/1990
  2640. ' -------------------------------------------------------------------------
  2641.    SUB LineEdit (MsgLine, MaxLen) STATIC
  2642.  
  2643.    ZWaitExpired = ZFalse
  2644.    ZStopInterrupts = ZTrue
  2645.    ZTabSize=5
  2646.    ZAutoLogoff!=TIMER+ZWaitBeforeDisconnect
  2647.   
  2648.    '
  2649.    ' Expand The String
  2650.    '
  2651.    j$ = ""
  2652.    FOR t = 1 TO LEN(ZOutTxt$(MsgLine))
  2653.       IF MID$(ZOutTxt$(MsgLine), t, 1) = CHR$(9) THEN
  2654.          q = ZTabSize - ((LEN(j$) - 1) MOD ZTabSize)
  2655.          IF q = 1 THEN
  2656.             j$ = j$ + CHR$(9)
  2657.          ELSE
  2658.             j$ = j$ + SPACE$(q - 1) + CHR$(9)
  2659.          END IF
  2660.       ELSE
  2661.          j$ = j$ + MID$(ZOutTxt$(MsgLine), t, 1)
  2662.       END IF
  2663.    NEXT
  2664.    LSET ZLineMes$ = j$
  2665.    Col = LEN(j$) + 1
  2666.  
  2667.  
  2668.    '
  2669.    ' Get Keyboard Stuff
  2670.    '
  2671.    DO
  2672.       call Carrier
  2673.       if ZSubParm = -1 then exit sub
  2674.       i$ = ""
  2675.       CALL FindFKey
  2676.       IF ZKeyPressed$ <> "" THEN
  2677.          i$ = ZKeyPressed$
  2678.       ELSEIF NOT ZLocalUser AND ZCommPortStack$ <> "" THEN
  2679.          i$ = LEFT$(ZCommPortStack$, 1)
  2680.          ZCommPortStack$ = RIGHT$(ZCommPortStack$, LEN(ZCommPortStack$) - 1)
  2681.       ELSEIF NOT ZLocalUser THEN
  2682.          CALL EofComm(Char)
  2683.          SendRemote = ZRemoteEcho
  2684.          IF Char <> -1 THEN
  2685.             ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  2686.             CALL GetCom(i$)
  2687.          ELSE
  2688.             CALL CheckTime(ZAutoLogoff!, TempElapsed!, 1)
  2689.             IF TempElapsed! <= 0 THEN
  2690.                ZWaitExpired = ZTrue
  2691.                EXIT SUB
  2692.             END IF
  2693.             CALL Carrier
  2694.             IF ZSubParm = -1 THEN EXIT SUB
  2695.          END IF
  2696.       END IF
  2697.  
  2698.       IF i$ <> "" THEN
  2699.          SELECT CASE ASC(i$)
  2700.             CASE 13           ' Carriage Return
  2701.                '
  2702.                ' Accept Changes
  2703.                '
  2704.                IF SendRemote THEN CALL PutCom(CHR$(13))
  2705.                IF ZLocalUser OR ZSnoop THEN CALL LPrnt("", 1)
  2706.                IF SendRemote AND ZLineFeeds THEN
  2707.                   CALL PutCom(ZLineFeed$)
  2708.                END IF
  2709.                EXIT DO
  2710.             CASE 8            ' BackSpace
  2711.                IF Col > 1 THEN
  2712.                   '
  2713.                   ' Kill Tab
  2714.                   '
  2715.                   IF MID$(ZLineMes$, Col - 1, 1) = CHR$(9) THEN
  2716.                      q = 0
  2717.                      FOR t = Col - 1 TO (INT((Col - 2) / ZTabSize) * ZTabSize + 1) STEP -1
  2718.                         IF MID$(ZLineMes$, t, 1) <> " " AND MID$(ZLineMes$, t, 1) <> CHR$(9) THEN
  2719.                            EXIT FOR
  2720.                         END IF
  2721.                         IF SendRemote THEN CALL PutCom(CHR$(8)+" "+chr$(8))
  2722.                         IF ZLocalUser OR ZSnoop THEN CALL LPrnt(CHR$(8)+" "+chr$(8), 0)
  2723.                         q = q + 1
  2724.                      NEXT
  2725.                      Col = Col - q
  2726.                   '
  2727.                   ' Kill Normal Character
  2728.                   '
  2729.                   ELSE
  2730.                      IF SendRemote THEN CALL PutCom(CHR$(8)+" "+chr$(8))
  2731.                      IF ZLocalUser OR ZSnoop THEN CALL LPrnt(CHR$(8)+" "+chr$(8), 0)
  2732.                      Col = Col - 1
  2733.                   END IF
  2734.                END IF
  2735.             CASE 26           ' Ctl-Y
  2736.                '
  2737.                ' Kill Entire Line
  2738.                '
  2739.                FOR t = 1 TO Col - 1
  2740.                   IF SendRemote THEN CALL PutCom(CHR$(8)+" "+chr$(8))
  2741.                   IF ZLocalUser OR ZSnoop THEN CALL LPrnt(CHR$(8)+" "+chr$(8), 0)
  2742.                NEXT
  2743.                Col = 1
  2744.             CASE 27           ' Escape
  2745.                '
  2746.                ' Abort Edits
  2747.                '
  2748.                FOR t = 1 TO Col - 1  ' Delete Editted Line
  2749.                   IF SendRemote THEN CALL PutCom(CHR$(8))
  2750.                   IF ZLocalUser OR ZSnoop THEN CALL LPrnt(CHR$(8), 0)
  2751.                NEXT
  2752.                FOR t = 1 TO Col - 1  ' Delete Editted Line
  2753.                   IF SendRemote THEN CALL PutCom(" ")
  2754.                   IF ZLocalUser OR ZSnoop THEN CALL LPrnt(" ", 0)
  2755.                NEXT
  2756.                FOR t = 1 TO Col - 1  ' Delete Editted Line
  2757.                   IF SendRemote THEN CALL PutCom(CHR$(8))
  2758.                   IF ZLocalUser OR ZSnoop THEN CALL LPrnt(CHR$(8), 0)
  2759.                NEXT
  2760.                FOR t = 1 TO LEN(j$)  ' Paint Old Line
  2761.                   IF MID$(j$, t, 1) = CHR$(9) THEN
  2762.                      IF SendRemote THEN CALL PutCom(" ")
  2763.                      IF ZLocalUser OR ZSnoop THEN CALL LPrnt(" ", 0)
  2764.                   ELSE
  2765.                      IF SendRemote THEN CALL PutCom(MID$(j$, t, 1))
  2766.                      IF ZLocalUser OR ZSnoop THEN CALL LPrnt(MID$(j$, t, 1), 0)
  2767.                   END IF
  2768.                NEXT
  2769.                IF ZLocalUser OR ZSnoop THEN CALL LPrnt("", 1)
  2770.                IF SendRemote AND ZLineFeeds THEN CALL PutCom(ZLineFeed$)
  2771.                EXIT SUB
  2772.             CASE 9            ' Tab
  2773.                '
  2774.                ' Add Tab
  2775.                '
  2776.                IF Col < ((INT(MaxLen / ZTabSize) - 1) * ZTabSize) THEN
  2777.                   q = ZTabSize - ((Col - 1) MOD ZTabSize)
  2778.                   FOR t = 1 TO q - 1
  2779.                      MID$(ZLineMes$, Col + t - 1, 1) = " "
  2780.                      IF SendRemote THEN CALL PutCom(" ")
  2781.                      IF ZLocalUser OR ZSnoop THEN CALL LPrnt(" ", 0)
  2782.                   NEXT
  2783.                   MID$(ZLineMes$, Col + q - 1, 1) = CHR$(9)
  2784.                   IF SendRemote THEN CALL PutCom(" ")
  2785.                   IF ZLocalUser OR ZSnoop THEN CALL LPrnt(" ", 0)
  2786.                   Col = Col + q
  2787.                ELSE
  2788.                   CALL SkipLine(1)
  2789.                   EXIT DO
  2790.                END IF
  2791.                ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  2792.             CASE IS < 32      ' Tripe Ignore It
  2793.             CASE ELSE
  2794.                '
  2795.                ' Insert Character
  2796.                '
  2797.                IF i$ = " " AND Col > MaxLen - 3 THEN
  2798.                   CALL SkipLine(1)
  2799.                   EXIT DO
  2800.                END IF
  2801.                MID$(ZLineMes$, Col, 1) = i$
  2802.                IF SendRemote THEN CALL PutCom(i$)
  2803.                IF ZLocalUser OR ZSnoop THEN CALL LPrnt(i$, 0)
  2804.                Col = Col + 1
  2805.                ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  2806.          END SELECT
  2807.  
  2808.      if i$=" " and Col>=MaxLen-3 then
  2809.             call SkipLine(1)
  2810.             exit do
  2811.          endif
  2812.      if Col>=MaxLen then
  2813.             WasZ=Col-1
  2814.             do while mid$(ZLineMes$,WasZ,1)<>" " and mid$(ZLineMes$,WasZ,1)<>chr$(9) and WasZ>0
  2815.                WasZ=WasZ-1
  2816.             loop
  2817.             if WasZ=0 then exit do
  2818.             ZOutTxt$(MsgLine)=left$(ZLineMes$,WasZ-1)
  2819.             ZOutTxt$(MsgLine+1)=mid$(ZLineMes$,WasZ+1,Col-WasZ-1)
  2820.             for t=1 to Col-WasZ-1
  2821.                IF SendRemote THEN CALL PutCom(chr$(8)+" "+chr$(8))
  2822.                IF ZLocalUser OR ZSnoop THEN CALL LPrnt(chr$(8)+" "+chr$(8), 0)
  2823.             next
  2824.             call SkipLine(1)
  2825.             exit sub
  2826.          endif
  2827.          ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  2828.       END IF
  2829.    LOOP
  2830.    
  2831.    Col=Col-1
  2832.    if Col<=0 then
  2833.       ZOutTxt$(MsgLine) = ""  ' Return a null value
  2834.       exit sub
  2835.    endif
  2836.    '
  2837.    ' Pack The String
  2838.    '
  2839.    j$ = ""
  2840.    FOR t = Col TO 1 STEP -1
  2841.       j$ = MID$(ZLineMes$, t, 1) + j$
  2842.       IF MID$(ZLineMes$, t, 1) = CHR$(9) THEN
  2843.          '
  2844.          ' Shrink Expanded Tabs To A Single Tab (chr$(9))
  2845.          '
  2846.          q = 0
  2847.          FOR n = t TO (INT((t - 1) / ZTabSize) * ZTabSize + 1) STEP -1
  2848.             IF MID$(ZLineMes$, n, 1) <> " " AND MID$(ZLineMes$, n, 1) <> CHR$(9) THEN
  2849.                EXIT FOR
  2850.             END IF
  2851.             q = q + 1
  2852.          NEXT
  2853.          t = t - q + 1
  2854.       END IF
  2855.    NEXT
  2856.    ZOutTxt$(MsgLine) = j$  ' Return the editted value
  2857. END SUB
  2858.  
  2859.  
  2860. 3952 ' $SUBTITLE: 'KillMsg - subroutine to delete messages'
  2861. ' $PAGE
  2862. '
  2863. '  NAME    -- KillMsg
  2864. '
  2865. '  INPUTS  --     PARAMETER                    MEANING
  2866. '              MsgToKill                   MESSAGE NUMBER TO KILL
  2867. '              ActiveMessages              NUMBER ACTIVE MESSAGES
  2868. '
  2869. '  OUTPUTS --  NONE
  2870. '
  2871. '  PURPOSE --  To kill/delete old or unnecessary messages
  2872. '
  2873.      SUB KillMsg (MsgToKill,ActiveMessages) STATIC
  2874. '
  2875.      FIELD #1,128 AS ZMsgRec$
  2876.      WasQX = 1
  2877. 3955 IF WasQX > ActiveMessages THEN _
  2878.         ZOutTxt$ = "No such msg #" + _
  2879.              STR$(MsgToKill) : _
  2880.         GOTO 4031
  2881.      IF ZMsgPtr(WasQX,2) = MsgToKill AND MsgToKill => 1 THEN _
  2882.         GOTO 3970
  2883.      WasQX = WasQX + 1
  2884.      GOTO 3955
  2885. 3970 ZSubParm = 3
  2886.      CALL FileLock
  2887.      GET 1,ZMsgPtr(WasQX,1)
  2888.      IF ZUserSecLevel >= ZSecKillAny THEN _
  2889.         GOTO 4030
  2890. 3980 ZWasZ$ = MID$(ZMsgRec$,101,15)
  2891.      CALL Trim (ZWasZ$)
  2892.      IF LEN(ZWasZ$) = 0 THEN _
  2893.         GOTO 4030
  2894. 3990 IF ZWasZ$ = "^READ^" OR ZWasZ$ = "^KILL^" THEN _
  2895.         CALL MsgNameMatch (ZActiveUserName$,"",6,MsgFromCaller) : _
  2896.         CALL MsgNameMatch (ZActiveUserName$,"",37,MsgToCaller) : _
  2897.         IF (MsgFromCaller or MsgToCaller) THEN _
  2898.            GOTO 4030 _
  2899.         ELSE ZMsgPswd = ZTrue : _
  2900.              ZAttemptsAllowed = 0 : _
  2901.              ZOutTxt$ = "Only sender & receiver can kill" : _
  2902.              GOTO 4031
  2903. 4000 IF LEFT$(ZWasZ$,1) = "!" THEN _
  2904.         ZWasZ$ = MID$(ZWasZ$,2)
  2905. 4010 ZPswdSave$ = ZWasZ$ + _
  2906.                       SPACE$(15 - LEN(ZWasZ$))
  2907.      ZAttemptsAllowed = 1
  2908.      ZMsgPswd = ZTrue
  2909.      CALL PassWrd
  2910.      IF ZPswdFailed THEN _
  2911.         GOTO 4031
  2912. 4030 MID$(ZMsgRec$,116,1) = ZDeletedMsg$
  2913.      PUT 1,LOC(1)
  2914.      ZSubParm = 4
  2915.      CALL FileLock
  2916.      ZOutTxt$ = "Killed Msg # " + _
  2917.           STR$(MsgToKill)
  2918.      CALL UpdtCalr (ZOutTxt$,1)
  2919. 4031 ZSubParm = 5
  2920.      CALL TPut
  2921.      END SUB
  2922. 4554 ' $SUBTITLE: 'SetThread - Sets up the interface for threading'
  2923. ' $PAGE
  2924. '
  2925. '  NAME    -- SetThread
  2926. '
  2927. '  INPUTS  --     PARAMETER                    MEANING
  2928. '                 CurMsgNum                 Current message number
  2929. '                 CurSubj$                  Current message subject
  2930. '
  2931. '  OUTPUTS --  ZUserIn$()                   Search msg by string
  2932. '              ZWasQ                        0 if thread cancelled
  2933. '
  2934. '  PURPOSE --  Find out how the caller wants to thread -
  2935. '              i.e. search messages by matching subject -
  2936. '              forward from current, back from current,
  2937. '              or forward from top of messages
  2938. '
  2939.      SUB SetThread (CurMsgNum,CurSubj$) STATIC
  2940.      IF ZWasQ > 1 THEN _
  2941.         ZWasZ$ = ZUserIn$(2) : _
  2942.         GOTO 4657
  2943. 4656 ZOutTxt$ = "THREAD: +)forward, -)back, 1)from origin ([ENTER] quits)"
  2944.      ZTurboKey = -ZTurboKeyUser
  2945.      ZSubParm = 1
  2946.      CALL TGet
  2947.      IF ZWasQ = 0 OR ZSubParm = -1 THEN _
  2948.         EXIT SUB
  2949.      ZWasZ$ = ZUserIn$(1)
  2950. 4657 ZWasZ$ = LEFT$(ZWasZ$,1)
  2951.      WasX = INSTR("+-1",ZWasZ$)
  2952.      IF WasX = 0 THEN _
  2953.         GOTO 4656
  2954.      ZUserIn$(1) = "R"
  2955.      IF WasX = 1 THEN _
  2956.         CurMsgNum = CurMsgNum + 1 _
  2957.      ELSE IF WasX = 2 THEN _
  2958.              CurMsgNum = CurMsgNum - 1 _
  2959.           ELSE CurMsgNum = 1 : _
  2960.                ZWasZ$ = "+"
  2961.      ZUserIn$(3) = MID$(STR$(CurMsgNum),2) + ZWasZ$
  2962.      IF LEN(CurSubj$) < 4 OR LEFT$(CurSubj$,3) <> "(R)" THEN _
  2963.         ZUserIn$(2) = CurSubj$ _
  2964.      ELSE ZUserIn$(2) = MID$(CurSubj$,4)
  2965.      ZUserIn$(2) = LEFT$(ZUserIn$(2) + "  ",22)
  2966.      ZLastIndex = 3
  2967.      ZAnsIndex = 1
  2968.      ZWasQ = 3
  2969.      END SUB
  2970. 4773 ' $SUBTITLE: 'SysopChat - chat with sysop'
  2971. ' $PAGE
  2972. '
  2973. '  NAME    -- SysopChat
  2974. '
  2975. '  INPUTS  --     PARAMETER                    MEANING
  2976. '  OUTPUTS --  ZWasCM                     True if chat active
  2977. '
  2978. '  PURPOSE --  Lets sysop chat interactively with caller
  2979. '
  2980.      SUB SysopChat STATIC
  2981.      ZWasCM = ZTrue
  2982.      TimeChatStarted! = TIMER
  2983.      ZSubParm = 1
  2984.      CALL Line25
  2985.      ZOutTxt$(2) = ""
  2986. 4775 CALL LineEdit (1,72)
  2987.      IF ZKeyPressed$ = ZEscape$ OR _
  2988.         ZSubParm < 0 THEN _
  2989.         GOTO 4777
  2990.      ZOutTxt$(1) = ""
  2991.      IF ZOutTxt$(2) <> "" THEN _
  2992.         ZOutTxt$ = ZOutTxt$(2) : _
  2993.         ZOutTxt$(1) = ZOutTxt$(2) : _
  2994.         ZOutTxt$(2) = "" _
  2995.      ELSE ZOutTxt$ = ""
  2996.      ZSubParm = 4
  2997.      CALL TPut
  2998.      IF ZSubParm > -1 THEN _
  2999.         GOTO 4775
  3000. 4777 ZWasCM = 0
  3001.      CALL CheckTime(TimeChatStarted!,Elapsed!, 2)
  3002.      ZSecsPerSession! = ZSecsPerSession! + Elapsed!
  3003.      IF NOT ZLocalUser THEN _
  3004.         ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  3005.      CALL QuickTPut("  Chat ended.  Returning to normal operation",2)
  3006.      END SUB
  3007. 5100 ' $SUBTITLE: 'RemNonAlf - removes non-alpha chars from a string'
  3008. ' $PAGE
  3009. '
  3010. '  NAME    -- RemNonAlf
  3011. '
  3012. '  INPUTS  --     PARAMETER                    MEANING
  3013. '                 Strng$                   String to check
  3014. '                 MinChar                  Remove chars with this
  3015. '                                          ASCII value or lower
  3016. '                 MaxChar                  Remove chars with this
  3017. '                                          ASCII value or higher
  3018. '
  3019. '  OUTPUTS --       Strng$                 String returned
  3020. '  PURPOSE --  CALCULATE THE ELASPED TIME A USER HAS BEEN ON
  3021. '
  3022.      SUB RemNonAlf (Strng$,MinChar,MaxChar) STATIC
  3023.      Last = LEN(Strng$)
  3024.      WasJ = 1
  3025.      WHILE WasJ <= Last
  3026.         WasK = ASC(MID$(Strng$,WasJ))
  3027.         IF WasK > MinChar AND WasK < MaxChar THEN _
  3028.            WasJ = WasJ + 1 _
  3029.         ELSE Strng$ = LEFT$(Strng$,WasJ - 1) + _
  3030.                       RIGHT$(Strng$,Last - WasJ) : _
  3031.              Last = Last - 1
  3032.      WEND
  3033.      END SUB
  3034. 5200 ' $SUBTITLE: 'PageLen - Sets lines per page'
  3035. ' $PAGE
  3036. '
  3037. '  NAME    -- PageLen
  3038. '
  3039. '  INPUTS  --     PARAMETER                    MEANING
  3040. '               ZPageLength              Current page length
  3041. '
  3042. '  OUTPUTS --   ZPageLength              New page length
  3043. '
  3044. '  PURPOSE --  Change default lines per page
  3045. '
  3046.      SUB PageLen STATIC
  3047. 5202 ZOutTxt$ = "CHANGE page length from" + _
  3048.           STR$(ZPageLength) + _
  3049.           " TO (0-255, 0=continuous)"
  3050.      CALL PopCmdStack
  3051.      IF ZWasQ = 0 OR ZSubParm = -1 THEN _
  3052.         CALL QuickTPut1 ("No change") : _
  3053.         EXIT SUB
  3054. 5230 CALL CheckInt (ZUserIn$(ZAnsIndex))
  3055.      IF ZErrCode <> 0 THEN _
  3056.         GOTO 5202
  3057.      IF ZTestedIntValue < 0 OR _
  3058.         ZTestedIntValue > 255 THEN _
  3059.         GOTO 5202
  3060.      ZPageLength = ZTestedIntValue
  3061.      CALL QuickTPut1 ("Page Length Set to" + STR$(ZPageLength))
  3062.      END SUB
  3063. 5507 ' $SUBTITLE: 'Baud450 -- Changes 300 baud to 450'
  3064. ' $PAGE
  3065. '  NAME    -- Baud450
  3066. '
  3067. '  INPUTS  -- PARAMETER             MEANING
  3068. '             ZBPS
  3069. '
  3070. '  OUTPUTS -- ZBPS
  3071. '
  3072. '  PURPOSE -- Allow 300 baud modems to bump up to 450 baud
  3073. '
  3074.      SUB Baud450 STATIC
  3075.      IF ZBPS <> -1 THEN _
  3076.         CALL QuickTPut1 ("Sorry, only 300 baud can change speed") : _
  3077.         EXIT SUB
  3078.      IF ZFossil THEN _
  3079.         CALL QuickTPut1 ("Sorry, 450 baud NOT supported under FOSSIL") : _
  3080.         EXIT SUB
  3081.      ZOutTxt$ = "Change to 450 baud (Y,[N])"
  3082.      ZTurboKey = -ZTurboKeyUser
  3083.      ZSubParm = 1
  3084.      CALL TGet
  3085.      IF ZSubParm = -1 OR NOT ZYes THEN _
  3086.         EXIT SUB
  3087. 5510 CALL QuickTPut1 ("Change your baud rate to 450")
  3088.      CALL DelayTime (9)
  3089.      ZWasC = 0
  3090.      ZBPS = -2
  3091.      CALL SetBaud
  3092.      ZOutTxt$ = " and then press [ENTER] until I respond"
  3093.      ZSubParm = 9
  3094.      CALL TGet
  3095. 5530 ZWasC = ZWasC + 1
  3096.      CALL Carrier
  3097.      IF ZSubParm = -1 THEN _
  3098.         EXIT SUB
  3099.      IF ZWasC = 20 THEN _
  3100.         CALL UpdtCalr ("Baud change failed",1) : _
  3101.         ZBPS = -1 : _
  3102.         CALL SetBaud : _
  3103.         EXIT SUB
  3104.      CALL DelayTime (1)
  3105. 5535 CALL EofComm (Char)
  3106.      IF Char = -1 THEN _
  3107.         GOTO 5530
  3108. 5536 CALL PutCom(ZOutTxt$)
  3109.      IF ZOutTxt$ = "" THEN _
  3110.         ZOutTxt$ = " "
  3111.      IF ASC(ZOutTxt$) = 13 THEN _
  3112.         GOTO 5540
  3113.      IF ZSubParm = -1 THEN _
  3114.         EXIT SUB
  3115. 5537 GOTO 5530
  3116. 5540 ZOutTxt$ = "Changed to 450 baud"
  3117.      CALL QuickTPut1 (ZOutTxt$)
  3118.      CALL UpdtCalr (ZOutTxt$,1)
  3119.      ZBPS = -2
  3120.      ZOutTxt$ = ""
  3121.      END SUB
  3122. 9140 ' $SUBTITLE: 'GetTime - subroutine to calculate elapsed time'
  3123. ' $PAGE
  3124. '
  3125. '  NAME    -- GetTime
  3126. '
  3127. '  INPUTS  --     PARAMETER                    MEANING
  3128. '                ZTimeLoggedOn$
  3129. '
  3130. '  OUTPUTS --  ZSessionHour               NUMBER OF HOURS ON
  3131. '              ZSessionMin                NUMBER OF MINUTES ON
  3132. '              ZSessionSec                NUMBER OF SECONDS ON
  3133. '
  3134. '  PURPOSE --  Calculate the elapsed time a user has been on
  3135. '
  3136.      SUB GetTime STATIC
  3137.      CALL CheckTime(ZUserLogonTime!, TempElapsed!, 2)
  3138.      ZSessionHour = TempElapsed! / 3600
  3139.      ZSessionMin = (TempElapsed! - ZSessionHour * 3600!) / 60
  3140.      ZSessionSec = TempElapsed! - (ZSessionHour * 3600! + ZSessionMin * 60!)
  3141.      IF ZSessionSec < 0 THEN _
  3142.         ZSessionSec = ZSessionSec + 60 : _
  3143.         ZSessionMin = ZSessionMin - 1
  3144.      IF ZSessionMin < 0 THEN _
  3145.         ZSessionMin = ZSessionMin + 60 : _
  3146.         ZSessionHour = ZSessionHour - 1
  3147.      END SUB
  3148. 9600 ' $SUBTITLE: 'DefaultU - subroutine to update user defauts'
  3149. ' $PAGE
  3150. '
  3151. '  NAME    -- DefaultU
  3152. '
  3153. '  INPUTS  --     PARAMETER                    MEANING
  3154. '             ZAutoDownDesired
  3155. '             ZBoldText$              Ansi bold (0 no, 1 yes)
  3156. '             ZCheckBulletLogon
  3157. '             ZExpertUser
  3158. '             ZWasGR
  3159. '             ZLastMsgRead
  3160. '             ZLineFeeds
  3161. '             ZNulls
  3162. '             ZPageLength
  3163. '             ZPromptBell
  3164. '             ZRegDate$
  3165. '             ZReqQuesAnswered
  3166. '             ZRightMargin
  3167. '             ZSkipFilesLogon
  3168. '             ZTimesLoggedOn
  3169. '             ZUpperCase
  3170. '             ZUserOption$
  3171. '             ZUserTextColor          Ansi of color (31-37)
  3172. '             ZUserXferDefault$
  3173. '
  3174. '  OUTPUTS--  USER.OPTONS$
  3175. '
  3176. '  PURPOSE --  To update the user's record with their options.
  3177. '  Meaning of graphics preference stored is as follows: where # is
  3178. '  value stored for the color.  E.g. if graphics perference for text
  3179. '  files is color, and preference for normal text is light yellow,
  3180. '  graphics preference stored is 38.  Colors are Red, Green, Yellow,
  3181. '  Blue, Purple, Cyan, and White.
  3182. '
  3183. '             normal                  bold
  3184. ' Graphics R  G  Y  B  P  C  W    R  G  Y  B  P  C  W
  3185. '   none  30 33 36 39 42 45 48 | 51 54 57 60 63 66 69
  3186. '   ansi  31 34 37 40 43 46 49 | 52 55 58 61 64 67 70
  3187. '  color  32 35 38 41 44 47 50 | 53 56 59 62 65 68 71
  3188. '
  3189.      SUB DefaultU STATIC
  3190.      ZWasA =    -ZPromptBell          -2 * ZExpertUser _
  3191.             -4 * ZNulls               -8 * ZUpperCase _
  3192.            -16 * ZLineFeeds          -32 * ZCheckBulletLogon _
  3193.            -64 * ZSkipFilesLogon    -128 * ZAutoDownDesired _
  3194.           -256 * ZReqQuesAnswered   -512 * ZMailWaiting _
  3195.          -1024 * (NOT ZHiLiteOff)  -2048 * ZTurboKeyUser
  3196.      WasX = 3*ZUserTextColor - 63 + 21*VAL(ZBoldText$) + ZWasGR
  3197.      IF WasX < 1 OR WasX > 255 THEN _
  3198.         WasX = 48
  3199.      LSET ZUserOption$ = _
  3200.         MKI$(ZTimesLoggedOn) + _
  3201.         MKI$(ZLastMsgRead) + _
  3202.         ZUserXferDefault$ + _
  3203.         CHR$(WasX) + _
  3204.         MKI$(ZRightMargin) + _
  3205.         MKI$(ZWasA) + _
  3206.         ZRegDate$ + _
  3207.         CHR$(ZPageLength) + _
  3208.         ZEchoer$
  3209.      END SUB
  3210. 9801 ' $SUBTITLE: 'WhosOn - subroutine to display who is on'
  3211. ' $PAGE
  3212. '
  3213. '  NAME    -- WhosOn
  3214. '
  3215. '  INPUTS  --     PARAMETER                    MEANING
  3216. '                NumNodes                   # of nodes to check
  3217. '                ZActiveMessageFile$        Current message file
  3218. '                ZOrigMsgFile$              Main msg file
  3219. '
  3220. '  OUTPUTS --  None
  3221. '
  3222. '  PURPOSE --  To display who is on each node.
  3223. '
  3224.      SUB WhosOn (NumNodes) STATIC
  3225.      WasA1$ = ZActiveMessageFile$
  3226.      ZActiveMessageFile$ = ZOrigMsgFile$
  3227.      CALL OpenMsg
  3228.      FIELD 1, 128 AS ZMsgRec$
  3229.      FOR NodeIndex = 2 TO NumNodes + 1
  3230.         GET 1,NodeIndex
  3231.         ZOutTxt$ = ZFG1$ + "Node" + _
  3232.              STR$(NodeIndex - 1) + ZFG2$
  3233.         RecIndex = VAL(MID$(ZMsgRec$,44,2))
  3234.         IF RecIndex = 0 THEN _
  3235.            RecIndex = -1
  3236.         WasAX$ = MID$(ZBaudRates$,(-5 * RecIndex ),5) + _
  3237.               " BAUD: "
  3238.         IF MID$(ZMsgRec$,55,2) = "-1" AND NOT ZSysop THEN _
  3239.            ZWasY$ = "SYSOP" + SPACE$(21) _
  3240.         ELSE ZWasY$ = MID$(ZMsgRec$,1,26)
  3241.         WasAX$ = WasAX$ + ZFG3$ + ZWasY$
  3242.         IF MID$(ZMsgRec$,40,2) <> "-1" THEN _
  3243.            WasAX$ = WasAX$ + ZFG4$ + MID$(ZMsgRec$,93,22)
  3244.         IF MID$(ZMsgRec$,57,1) = "A" THEN _
  3245.            ZOutTxt$ = ZOutTxt$ + "  Online at " + _
  3246.                 WasAX$ _
  3247.         ELSE IF NOT ZSysop THEN _
  3248.                 ZOutTxt$ = ZOutTxt$ + _
  3249.                      " Waiting for next caller" _
  3250.              ELSE ZOutTxt$ = ZOutTxt$ + _
  3251.                        " Offline at " + _
  3252.                        WasAX$
  3253.         CALL QuickTPut1 (ZOutTxt$)
  3254.         CALL AskMore ("",ZTrue,ZTrue,ZAnsIndex,ZFalse)
  3255.         IF ZNo THEN _
  3256.            NodeIndex = NumNodes + 2
  3257.      NEXT
  3258.      ZActiveMessageFile$ = WasA1$
  3259.      CALL QuickTPut (ZEmphasizeOff$,0)
  3260.      END SUB
  3261. 10410 ' $SUBTITLE: 'RecoverMsg - sub to recover deleted messages'
  3262. ' $PAGE
  3263. '
  3264. '  NAME    -- RecoverMsg
  3265. '
  3266. '  INPUTS  --     PARAMETER                    MEANING
  3267. '               MsgToRecover          MESSAGE NUMBER TO RECOVER
  3268. '               FirstMsgRecord        RECORD # FOR First MSG
  3269. '
  3270. '  OUTPUTS --  ActionFlag                 SET TO 0 IF ERROR
  3271. '                                         SET TO -1 IF No ERROR
  3272. '
  3273. '  PURPOSE --  To recover deleted messages.  Note that this is only
  3274. '              possible if you have not compressed your message file
  3275. '              using config.
  3276. '
  3277.       SUB RecoverMsg (MsgToRecover,FirstMsgRecord,ActionFlag) STATIC
  3278.       FIELD #1,128 AS ZMsgRec$
  3279.       MsgRec = FirstMsgRecord
  3280. 10420 GET 1,MsgRec
  3281.       NumRecsInMsg = VAL(MID$(ZMsgRec$,117,4))
  3282.       IF NumRecsInMsg < 1 OR MsgRec => ZNextMsgRec THEN _
  3283.          ZWasY$ = "No Msg #" + _
  3284.               STR$(MsgToRecover) : _
  3285.          GOTO 10485
  3286. 10440 IF VAL(MID$(ZMsgRec$,2,4)) <> MsgToRecover THEN _
  3287.          MsgRec = MsgRec + NumRecsInMsg : _
  3288.          GOTO 10420
  3289. 10450 IF INSTR(ZMsgRec$,ZDeletedMsg$) <> 0 THEN _
  3290.          LSET ZMsgRec$ = LEFT$(ZMsgRec$,115) + _
  3291.                                 ZActiveMessage$ + _
  3292.                                 MID$(ZMsgRec$,117) : _
  3293.          PUT 1,LOC(1) : _
  3294.          ZWasY$ = "Restored Msg #" + _
  3295.               STR$(MsgToRecover) : _
  3296.          ActionFlag = ZTrue : _
  3297.          GOTO 10485
  3298. 10480 ZWasY$ = "Msg #" + _
  3299.            STR$(MsgToRecover) + _
  3300.            " not Dead"
  3301. 10485 CALL QuickTPut1 (ZWasY$)
  3302.       END SUB
  3303. 10600 ' $SUBTITLE: 'UpdateU -- Update the users record at logoff'
  3304. ' $PAGE
  3305. '  NAME    -- UpdateU
  3306. '
  3307. '  INPUTS  -- PARAMETER             MEANING
  3308. '             ZAdjustedSecurity
  3309. '             ZCurDate$
  3310. '             ZDnlds
  3311. '             ZElapsedTime
  3312. '             ZListDir
  3313. '             ZMainUserFileIndex
  3314. '             ZSecsPerSession!
  3315. '             ZUplds
  3316. '             ZUserSecLevel
  3317. '
  3318. '  OUTPUTS -- ZElapsedTime$
  3319. '             ZListNewDate$
  3320. '             ZSecLevel$
  3321. '             ZUserDnlds$
  3322. '             ZUserUplds$
  3323. '
  3324. '  PURPOSE -- Update the user record for the user when the user
  3325. '             exits RBBS-PC.
  3326. '
  3327.       SUB UpdateU (LoggingOff) STATIC
  3328.       IF ZActiveUserName$ = "" OR ZFirstName$ = "" THEN _
  3329.          EXIT SUB
  3330.       IF ZActiveUserFile$ = ZOrigUserFile$ THEN _
  3331.          ZUplds = ZGlobalUplds : _
  3332.          ZDnlds = ZGlobalDnlds : _
  3333.          ZDLToday! = ZGlobalDLToday! : _
  3334.          ZBytesToday! = ZGlobalBytesToday! : _
  3335.          ZDLBytes! = ZGlobalDLBytes! : _
  3336.          ZULBytes! = ZGlobalULBytes!
  3337.       IF ZUserFileIndex < 1 THEN _
  3338.          GOTO 10607
  3339.       UpdateDefaults = ZTrue
  3340. 10602 ZSubParm = 6
  3341.       CALL FileLock
  3342.       CALL OpenUser (HighestUserRecord)
  3343.       FIELD 5,31 AS ZUserName$, _
  3344.               15 AS ZPswd$, _
  3345.                2 AS ZSecLevel$, _
  3346.               14 AS ZUserOption$,  _
  3347.               24 AS ZCityState$, _
  3348.               3 AS MachineType$, _
  3349.               4 AS ZTodayDl$, _
  3350.               4 AS ZTodayBytes$, _
  3351.               4 AS ZDlBytes$, _
  3352.               4 AS ZULBytes$, _
  3353.               14 AS ZLastDateTimeOn$, _
  3354.                3 AS ZListNewDate$, _
  3355.                2 AS ZUserDnlds$, _
  3356.                2 AS ZUserUplds$, _
  3357.                2 AS ZElapsedTime$
  3358. 10604 GET 5,ZUserFileIndex
  3359.       IF UpdateDefaults THEN _
  3360.          CALL DefaultU
  3361.       IF ZListDir THEN _
  3362.          LSET ZListNewDate$ = CHR$(VAL(MID$(ZCurDate$,7,2))) + _
  3363.                                CHR$(VAL(MID$(ZCurDate$,1,2))) + _
  3364.                                CHR$(VAL(MID$(ZCurDate$,4,2)))
  3365. 10605 LSET ZUserDnlds$ = MKI$(ZDnlds)
  3366.       LSET ZUserUplds$ = MKI$(ZUplds)
  3367.       IF ZEnforceRatios THEN _
  3368.          LSET ZTodayDl$ = MKS$(ZDLToday!) : _
  3369.          LSET ZTodayBytes$ = MKS$(ZBytesToday!) : _
  3370.          LSET ZDlBytes$ = MKS$(ZDLBytes!) : _
  3371.          LSET ZULBytes$ = MKS$(ZULBytes!)
  3372.       CALL CheckTime (ZUserLogonTime!, ZSecsUsedSession!, 2)
  3373.       IF (NOT ZExitToDoors) AND LoggingOff THEN _
  3374.          TempElapsed! = ZElapsedTime + _
  3375.                        (ZSecsUsedSession! - ZTimeCredits!) / 60 : _
  3376.          ZTimeCredits! = 0 _
  3377.       ELSE TempElapsed! = ZElapsedTime
  3378.       IF TempElapsed! < -32767 THEN _
  3379.          TempElapsed! = -32767 _
  3380.       ELSE IF TempElapsed! > 32767 THEN _
  3381.          TempElapsed! = 32767
  3382.       LSET ZElapsedTime$ = MKI$(TempElapsed!)
  3383.       IF ZAdjustedSecurity THEN _
  3384.          LSET ZSecLevel$ = MKI$(ZUserSecLevel)
  3385.       PUT 5,ZUserFileIndex
  3386.       ZSubParm = 8
  3387.       CALL FileLock
  3388.       IF ZActiveUserFile$ <> ZOrigUserFile$ AND LoggingOff THEN _
  3389.          ZActiveUserFile$ = ZOrigUserFile$ : _
  3390.          ZUserFileIndex = ZOrigUserFileIndex : _
  3391.          UpdateDefaults = ZFalse : _
  3392.          GOTO 10602
  3393. 10607 IF ZExitToDoors OR NOT LoggingOff THEN _
  3394.          EXIT SUB
  3395.       Temp = ZMinsPerSession
  3396.       IF ZMaxPerDay > 0 THEN _
  3397.          Temp = ZMaxPerDay - TempElapsed! : _
  3398.          IF Temp > ZMinsPerSession THEN _
  3399.             Temp = ZMinsPerSession
  3400.       Temp = -(Temp > 0) * Temp
  3401.       CALL QuickTPut1 (STR$(Temp)+" min left for next call today")
  3402.       CALL QuickTPut1 (ZFirstName$ + ", Thanks and please call again!")
  3403.       IF NOT ZHiLiteOff THEN _
  3404.          CALL QuickTPut1 (ZColorReset$)
  3405.       CALL DelayTime (8 + ZBPS)
  3406.       END SUB
  3407. 10935 ' $SUBTITLE: 'DosExit -- Setup to exit to DOS for ZSysop'
  3408. ' $PAGE
  3409. '  NAME    -- DosExit
  3410. '
  3411. '  INPUTS  -- PARAMETER             MEANING
  3412. '             ZComPort$
  3413. '             ZDoorsTermType
  3414. '             ZMultiLinkPresent
  3415. '             ZRBBSBat$
  3416. '             ZRedirectIOMethod
  3417. '             ZUseDeviceDriver$
  3418. '
  3419. '  OUTPUTS -- ZWasQ                    NUMBER OF LINES TO WRITE OUT TO
  3420. '                                      ZRCTTYBat$
  3421. '             ZUserIn$()               LINES TO WRITE OUT TO ZRCTTYBat$
  3422. '
  3423. '  PURPOSE -- Set up ZUserIn$() and ZWasQ in order to call "RBBSExit" and
  3424. '             exit to DOS for the remote RBBS-PC sysop
  3425. '
  3426.       SUB DosExit STATIC
  3427.       IF ZMultiLinkPresent AND _
  3428.          ZDoorsTermType > 0 THEN _
  3429.          ZFF = 0 : _
  3430.          GOTO 10950
  3431.       ZOutTxt$(1) = "ECHO OFF"
  3432.       IF ZUseDeviceDriver$ <> "" THEN _
  3433.          Port$ = ZUseDeviceDriver$ _
  3434.       ELSE Port$ = "COM" + RIGHT$(ZComPort$,1)
  3435.       IF ZRedirectIOMethod THEN _
  3436.          ZFF = 5 : _
  3437.          ZOutTxt$(2) = "CTTY " + _
  3438.                  Port$ : _
  3439.          ZOutTxt$(3) = ZDiskForDos$ + _
  3440.                  "COMMAND" : _
  3441.          ZOutTxt$(4) = "CTTY CON" : _
  3442.          ZOutTxt$(5) = ZRBBSBat$ _
  3443.       ELSE ZFF = 3 : _
  3444.            ZOutTxt$(2) = ZDiskForDos$ + _
  3445.                    "COMMAND >" + _
  3446.                    Port$ + _
  3447.                    " <" + _
  3448.                    Port$ : _
  3449.            ZOutTxt$(3) = ZRBBSBat$
  3450. 10950 CALL AMorPM
  3451.       CALL UpdtCalr ("Exited to DOS at " + ZTime$,2)
  3452.       CALL QuickTPut1 ("RBBS-PC " + ZVersionID$)
  3453.       CALL QuickTPut1 ("SYSOP in Remote Console Mode")
  3454.       CALL RBBSExit (ZOutTxt$(),ZFF)
  3455.       END SUB
  3456. 10976 ' $SUBTITLE: 'WordInFile -- Searches a file to find a word'
  3457. ' $PAGE
  3458. '  NAME    -- WordInFile
  3459. '
  3460. '  INPUTS  -- PARAMETER             MEANING
  3461. '             FilName$              FILE TO SEARCH IN
  3462. '             Strng$                STRING TO SEARCH FOR
  3463. '
  3464. '  OUTPUTS -- InFile                WHETHER STRING Found IN FILE
  3465. '
  3466. '  PURPOSE -- Searches for "Strng$" in file "FILNAME$."  Used to
  3467. '             limit doors and questionnaires to those specified
  3468. '             in their menu files.  The "Strng$" is capitalized
  3469. '             but not the lines in the file, so must be exact
  3470. '             case-sensitive match to be found.  The only character
  3471. '             that can immediately proceed or end a name to be
  3472. '             found must be a blank.
  3473. '
  3474.       SUB WordInFile (FilName$,Strng$,InFile) STATIC
  3475.       InFile = ZFalse
  3476.       CALL FindIt (FilName$)
  3477.       IF NOT ZOK THEN _
  3478.          EXIT SUB
  3479.       WasX = 0
  3480.       CALL AllCaps (Strng$)
  3481.       WHILE NOT EOF(2) AND WasX < 1
  3482.          LINE INPUT #2,ZOutTxt$
  3483.          WasY = 1
  3484. 10978    WasX = INSTR(WasY,ZOutTxt$,Strng$)
  3485.          IF WasX < 1 THEN _
  3486.             GOTO 10980
  3487.          WasY = WasX + 1
  3488.          IF WasX > 1 THEN _
  3489.             IF MID$(ZOutTxt$,WasX - 1,1) <> " " THEN _
  3490.                WasX = 0
  3491.          IF WasX > 0 THEN _
  3492.             WasL = LEN(Strng$) : _
  3493.             IF LEN(ZOutTxt$) => (WasX + WasL) THEN _
  3494.                IF MID$(ZOutTxt$,WasX + WasL,1) <> " " THEN _
  3495.                   WasX = 0
  3496.          IF WasX = 0 THEN _
  3497.             GOTO 10978
  3498. 10980 WEND
  3499.       CLOSE 2
  3500.       InFile = (WasX > 0)
  3501.       END SUB
  3502. 10983 ' $SUBTITLE: 'DoorExit -- Setup to exit to a "door"'
  3503. ' $PAGE
  3504. '  NAME    -- DoorExit
  3505. '
  3506. '  INPUTS  -- PARAMETER             MEANING
  3507. '             ZMultiLinkPresent
  3508. '             ZNodeID$
  3509. '             ZRBBSBat$
  3510. '             ZWasZ$
  3511. '
  3512. '  OUTPUTS -- ZWasQ                    NUMBER OF LINES TO WRITE OUT TO
  3513. '                                      ZRCTTYBat$
  3514. '             ZUserIn$()               LINES TO WRITE OUT TO ZRCTTYBat$
  3515. '
  3516. '  PURPOSE -- Set up ZUserIn$() and ZWasQ in order to call "EXITRBBS" and
  3517. '             exit RBBS-PC to invoke another program
  3518. '
  3519.       SUB DoorExit STATIC
  3520.       IF ZWasZ$ = "" OR _
  3521.          ZWasZ$ = "NONE" THEN _
  3522.          EXIT SUB
  3523.       CALL FindIt (ZWasZ$)
  3524.       IF NOT ZOK THEN _
  3525.          GOTO 10986
  3526.       ExitTo$ = LEFT$(ZWasZ$,LEN(ZWasZ$) - 4)
  3527.       ExitMethod$ = ""
  3528.       ZDooredTo$ = ExitTo$
  3529.       CALL FindIt (ZDoorsDef$)
  3530.       IF NOT ZOK THEN _
  3531.          ExitTo$ = ExitTo$ + " " + ZNodeID$ : _
  3532.          GOTO 10989
  3533. 10985 CALL ReadParms (ZOutTxt$(),8,1)
  3534.       IF ZErrCode > 0 THEN _
  3535.          ExitTo$ = ExitTo$ + " " + ZNodeID$ : _
  3536.          GOTO 10989
  3537.       IF ExitTo$ <> ZOutTxt$(1) THEN _
  3538.          GOTO 10985
  3539.       CALL CheckInt (ZOutTxt$(2))
  3540.       IF ZErrCode > 0 THEN _
  3541.          ZErrCode = 0 : _
  3542.          GOTO 10985
  3543.       IF ZUserSecLevel < ZTestedIntValue THEN _
  3544.          CALL QuickTPut1 ("Insufficient security for door") : _
  3545.          EXIT SUB
  3546.       WasX$ = LEFT$(ZOutTxt$(5),INSTR(ZOutTxt$(5)+" "," ")-1)
  3547.       CALL FindIt (WasX$)
  3548.       IF NOT ZOK THEN _
  3549.          GOTO 10986
  3550.       ZFileName$ = ZOutTxt$(3)
  3551.       ExitMethod$ = ZOutTxt$(4)
  3552.       ExitTemplate$ = ZOutTxt$(5)
  3553.       ZDoorDisplay$ = ZOutTxt$(7)
  3554.       DoorTime$ = ZOutTxt$(8)
  3555.       CALL AskUsers
  3556.       CALL SmartText (ExitTemplate$,ZFalse,ZFalse)
  3557.       CALL MetaGSR (ExitTemplate$,ZFalse)
  3558.       ExitTo$ = ExitTemplate$
  3559.       GOTO 10989
  3560. 10986 ZOutTxt$ = "Missing door program"
  3561.       CALL UpdtCalr (ZOutTxt$ + " " + ZWasZ$,1)
  3562.       ZSnoop = ZTrue
  3563.       CALL LPrnt (ZOutTxt$,1)
  3564.       EXIT SUB
  3565. 10989 IF ZTransferFunction = 3 THEN _
  3566.          ZWasY$ = "Registration" _
  3567.       ELSE ZWasY$ = ZDooredTo$
  3568.       ZOutTxt$ = ZWasY$ + _
  3569.            " door opened at " + _
  3570.            TIME$ + _
  3571.            " on " + _
  3572.            DATE$
  3573.       ZSubParm = 5
  3574.       CALL TPut
  3575.       CALL UpdtCalr (ZDooredTo$ + " door opened!",2)
  3576.       CLOSE 2
  3577.       OPEN "O",2,"DORINFO" + _
  3578.                  ZNodeFileID$ + _
  3579.                  ".DEF"
  3580.       PRINT #2,ZRBBSName$
  3581.       PRINT #2,ZSysopFirstName$
  3582.       PRINT #2,ZSysopLastName$
  3583.       IF ZLocalUser THEN _
  3584.          PRINT #2,"COM0" _
  3585.       ELSE PRINT #2,ZComPort$
  3586.       ZUserIn$ = MID$(ZBaudParity$,INSTR(ZBaudParity$," B"))
  3587.       PRINT #2,ZTalkToModemAt$;ZUserIn$
  3588.       PRINT #2,ZNetworkType
  3589.       IF ZGlobalSysop THEN _
  3590.          PRINT #2,"SYSOP" : _
  3591.          PRINT #2,"" _
  3592.       ELSE PRINT #2,ZFirstName$ : _
  3593.            PRINT #2,ZLastName$
  3594.       PRINT #2,ZCityState$
  3595.       PRINT #2,ZWasGR
  3596.       PRINT #2,ZUserSecLevel
  3597.       CALL TimeRemain (MinsRemaining)
  3598.       CALL CheckInt (DoorTime$)
  3599.       IF ZErrCode = 0 AND ZTestedIntValue > 0 THEN _
  3600.          IF MinsRemaining > ZTestedIntValue THEN _
  3601.             MinsRemaining = ZTestedIntValue
  3602.       PRINT #2,INT(MinsRemaining)
  3603.       PRINT #2,ZFossil
  3604.       IF ExitMethod$ = "S" THEN _
  3605.          CALL ShellExit (ExitTemplate$) : _
  3606.          ZExitToDoors = ZTrue : _
  3607.          CALL BufFile (ZDoorDisplay$,WasX) : _
  3608.          CALL DoorReturn _
  3609.       ELSE ZOutTxt$(1) = ZDiskForDos$ + _
  3610.                   "COMMAND /C " + _
  3611.                   ExitTo$ : _
  3612.            ZOutTxt$(2) = ZRBBSBat$ : _
  3613.            CALL RBBSExit (ZOutTxt$(),2)
  3614.       END SUB
  3615. 10992 ' $SUBTITLE: 'RBBSExit -- Setup to exit RBBS'
  3616. ' $PAGE
  3617. '  NAME    -- RBBSExit
  3618. '
  3619. '  INPUTS  -- PARAMETER             MEANING
  3620. '             LINE.ARA        Array of lines to write to batch file
  3621. '             NumLines        How many lines in array
  3622. '
  3623. '  OUTPUTS -- ZRCTTYBat$
  3624. '
  3625. '  PURPOSE -- To create a batch file that control can be passed to
  3626. '             and to exit RBBS-PC while still keeping carrier up
  3627. '
  3628.       SUB RBBSExit (LineAra$(1),NumLines) STATIC
  3629.       CLOSE 2
  3630.       IF NumLines = 0 THEN _
  3631.          GOTO 10994
  3632.       OPEN "O",2,ZRCTTYBat$
  3633.       FOR WasI = 1 TO NumLines
  3634.          IF LineAra$(WasI) <> "" THEN _
  3635.             PRINT #2,LineAra$(WasI)
  3636.       NEXT
  3637.       CLOSE 2
  3638. 10994 CLOSE 3
  3639.       ZExitToDoors = ZTrue
  3640.       IF NOT ZFossil THEN _
  3641.          OUT ZModemCntlReg,INP(ZModemCntlReg) OR 1
  3642.       IF NOT ZPrivateDoor THEN _
  3643.          CALL MLInit (2)
  3644. 10996 CALL UpdateU (ZTrue)
  3645.       CALL GetTime
  3646.       CALL SaveProf (1)
  3647.       IF NumLines = 0 THEN _
  3648.          EXIT SUB
  3649.       CALL DelayTime (9 + ZBPS)
  3650.       IF ZFossil THEN _
  3651.          CALL FOSExit(ZComPort)
  3652.       SYSTEM
  3653.       END SUB
  3654. 12000 ' $SUBTITLE: 'SetSection -- Setup section prompts'
  3655. ' $PAGE
  3656. '  NAME    -- SetSection         Doug Azzarito
  3657. '
  3658. '  INPUTS  -- PARAMETER             MEANING
  3659. '             ZMenuIndex      2 = user is in MAIN section
  3660. '                             3 = user is in FILE section
  3661. '                             4 = user is in UTIL section
  3662. '                             6 = user is in LIBR section
  3663. '
  3664. '  OUTPUTS -- ZSection$       4 character section name
  3665. '             ZActiveMenu$    1 character section name
  3666. '             ZSectionPrompt$ Section name (if ZShowSection config)
  3667. '             ZCmdPrompt$     Command input prompt string
  3668. '             ZSectionOpts$   List of options valid in this sect
  3669. '             ZInvalidOpts$   List of options invalid in this sect
  3670. '             ZSubSection     Index into security array for section
  3671. '
  3672. '  PURPOSE -- To build the prompt strings for the current section
  3673. '
  3674.       SUB SetSection STATIC
  3675.       IF ZMenuIndex <> 6 THEN _
  3676.          ZCurDirPath$ = ZDirPath$
  3677.       ON ZMenuIndex GOTO 12001, 12010,12005,12020,12001,12015
  3678. 12001 EXIT SUB
  3679. 12005 LSET ZSection$ = "FILE"
  3680.       ZSectionOpts$ = ZFileOpts$
  3681.       ZInvalidOpts$ = ZInvalidFileOpts$
  3682.       ZSubSection = ZBegFile
  3683.       GOTO 12025
  3684. 12010 LSET ZSection$ = "MAIN"
  3685.       ZSectionOpts$ = ZMainOpts$
  3686.       ZInvalidOpts$ = ZInvalidMainOpts$
  3687.       ZSubSection = ZBegMain
  3688.       GOTO 12025
  3689. 12015 LSET ZSection$ = "LIBR"
  3690.       ZSectionOpts$ = ZLibOpts$
  3691.       ZInvalidOpts$ = ZInvalidLibraryOpts$
  3692.       ZSubSection = ZBegLibrary
  3693.       ZCurDirPath$ = ZLibDirPath$
  3694.       GOTO 12025
  3695. 12020 LSET ZSection$ = "UTIL"
  3696.       ZSectionOpts$ = ZUtilOpts$
  3697.       ZInvalidOpts$ = ZInvalidUtilOpts$
  3698.       ZSubSection = ZBegUtil
  3699. 12025 ZActiveMenu$ = LEFT$(ZSection$,1)
  3700.       LSET ZLastCommand$ = ZActiveMenu$ + " "
  3701.       IF ZShowSection THEN _
  3702.          ZSectionPrompt$ = ZSection$ _
  3703.       ELSE ZSectionPrompt$ = "Your"
  3704.       IF ZCmndsInPrompt=0 THEN _
  3705.           ZSectionOpts$ = ""
  3706.       ZCmdPrompt$ = ZSectionPrompt$ + _
  3707.                         " command" + _
  3708.                         ZSectionOpts$
  3709.       END SUB
  3710. 12878 ' $SUBTITLE: 'UntilRight - asks question until answer okay'
  3711. ' $PAGE
  3712. '
  3713. '  NAME    -- UntilRight
  3714. '
  3715. '  INPUTS  -- PARAMETER             MEANING
  3716. '             Ques$         QUESTION TO BE ASKED THE USER
  3717. '             Ans$          LOCATION TO STORE THE ANSWER
  3718. '             MinLen        MINIMUM LENGTH OF ANSWER
  3719. '             MaxLen        MAX LENGTH OF ANSWER
  3720. '
  3721. '  OUTPUTS -- Ans$          RESPONSE TO THE QUESTION WHICH THE
  3722. '                                      CALLERS SAYS IS CORRECT
  3723. '
  3724. '  PURPOSE -- Subroutine to ask a user a question until the caller
  3725. '             responds that the answer is correct
  3726. '
  3727.       SUB UntilRight (Ques$,Ans$,MinLen,MaxLen) STATIC
  3728. 12880 ZSubParm = 1
  3729.       ZOutTxt$ = Ques$
  3730.       CALL TGet
  3731.       IF ZSubParm = -1 THEN _
  3732.          GOTO 12882
  3733.       IF ZWasQ = 0 THEN _
  3734.          GOTO 12880
  3735.       IF LEN(ZUserIn$(1)) > MaxLen THEN _
  3736.          CALL QuickTPut1 (STR$(MaxLen) + " chars max") : _
  3737.          GOTO 12880_
  3738.       ELSE IF LEN(ZUserIn$(1)) < MinLen THEN _
  3739.               CALL QuickTPut1 (STR$(MinLen) + " chars min") : _
  3740.               GOTO 12880
  3741.       Ans$ = ZUserIn$(1)
  3742.       ZOutTxt$ = ZUserIn$(1) + _
  3743.            ", right ([Y],N)"
  3744.       ZTurboKey = -ZTurboKeyUser
  3745.       ZSubParm = 1
  3746.       CALL TGet
  3747.       IF ZSubParm = -1 THEN _
  3748.          GOTO 12882
  3749.       IF ZNo THEN _
  3750.          GOTO 12880
  3751.       CALL AllCaps (Ans$)
  3752.       EXIT SUB
  3753. 12882 Ans$ = "GUEST"
  3754.       END SUB
  3755. 13660 ' $SUBTITLE: 'LogError - sub to log errors to CALLERS file'
  3756. ' $PAGE
  3757. '
  3758. '  NAME    -- LogError
  3759. '
  3760. '  INPUTS  --     PARAMETER                    MEANING
  3761. '                    ERR           ERROR NUMBER DETECTED BY BASIC
  3762. '                    ERL           Last LINE NUMBER ENCOUNTERED
  3763. '                                  PRIOR TO ENCOUNTERNING ERROR
  3764. '
  3765. '  OUTPUTS -- NONE
  3766. '
  3767. '  PURPOSE -- To set up a string to write to the callers log
  3768. '             indicating the date, time, error, and error line
  3769. '
  3770.       SUB LogError STATIC
  3771.       WasIX = ERR
  3772.       IF ERR < 1 THEN _
  3773.          WasIX = ZErrCode
  3774.       CALL UpdtCalr("+++ Error " + _
  3775.            STR$(WasIX) + _
  3776.            " line " + _
  3777.            STR$(ERL) + _
  3778.            " at " + _
  3779.            TIME$ + _
  3780.            " on " + _
  3781.            DATE$,2)
  3782.       END SUB
  3783. '
  3784. 20096 ' $SUBTITLE: 'CheckRatio - subroutine to print ul/dl ratio'
  3785. ' $PAGE
  3786. '
  3787. '  NAME    -- CheckRatio
  3788. '
  3789. '  INPUTS  --   PARAMETER                    MEANING
  3790. '               TellUser           TELL USER THEIR RATIO
  3791. '               ZDnlds             FILES DOWNLOADED
  3792. '               ZDLBytes!          BYTES DOWNLOADED
  3793. '               ZUplds             FILES UPLOADED
  3794. '               ZULBytes!          BYTES UPLOADED
  3795. '
  3796. '  OUTPUTS --   ZOK                 -1 if okay to download, 0 otherwise
  3797. '
  3798. '  PURPOSE -- To determine whether the users violated
  3799. '             their upload to download restriction
  3800. '
  3801.       SUB CheckRatio (TellUser) STATIC
  3802.       ZOK = ZTrue
  3803.       IF NOT ZEnforceRatios THEN _
  3804.          GOTO 20110
  3805.       IF ZRatioRestrict# <= 0 THEN _
  3806.          GOTO 20110
  3807. '
  3808. ' Detemine method of ratio checking.  Look ahead to amount downloaded
  3809. '
  3810.       IF ZByteMethod = 1 OR ZByteMethod = 3 THEN _
  3811.          Method$ = "Bytes" : _
  3812.          ULWork# = ZULBytes! : _
  3813.          DLWork# = ZDLBytes! + ZNumDnldBytes!
  3814.       IF ZByteMethod = 0 OR ZByteMethod = 2 THEN _
  3815.          Method$ = "Files" : _
  3816.          ULWork# = ZUplds : _
  3817.          DLWork# = ZDnlds + ZDownFiles
  3818.       IF ULWork# < ZInitialCredit# THEN _
  3819.          ULWork# = ZInitialCredit#
  3820.       IF ZByteMethod = 2 THEN _
  3821.          Today# = ZRatioRestrict# - ZDLToday! - ZDownFiles
  3822.       IF ZByteMethod = 3 THEN _
  3823.          Today# = ZRatioRestrict# - ZBytesToday! - ZNumDnldBytes!
  3824. '
  3825.       Ratio# = 0
  3826.       RatioSuffix$ = ":0"
  3827.       IF ULWork# > 0 THEN _
  3828.          Ratio# = (DLWork# / ULWork#) : _
  3829.          RatioSuffix$ = ":1"
  3830.       IF ZByteMethod > 1 THEN _
  3831.          ZOutTxt$ = "Today Downloaded Files: " + STR$(ZDLToday! + ZDownFiles) + _
  3832.               "  Bytes:" + STR$(ZBytesToday! + ZNumDnldBytes!) : _
  3833.          ZSubParm = 5 : _
  3834.          CALL TPut : _
  3835.          CALL SkipLine (1) : _
  3836.          GOTO 20100
  3837.       WasX$ = STR$(Ratio#)
  3838.       X = INSTR(WasX$,".")
  3839.       IF X > 0 THEN _
  3840.          WasX$ = LEFT$(WasX$,X+1)
  3841.       ZOutTxt$ = Method$ + " Downloaded:" + STR$(DLWork#) + _
  3842.               " Uploaded:" + _
  3843.               STR$(ULWork#) + _
  3844.               " Ratio:" + _
  3845.               WasX$ + _
  3846.               RatioSuffix$
  3847.       ZSubParm = 5
  3848.       CALL TPut
  3849. '
  3850. '  CHECK TO SEE IF THE USER HAS VIOLATED THEIR UL/DL RESTRICTION
  3851. '
  3852. 20100 IF NOT (ZRatioRestrict# > 0 AND TellUser) THEN _
  3853.          EXIT SUB
  3854.       IF ZByteMethod <= 1 THEN _
  3855.          GOTO 20105
  3856.       IF Today# < 0 THEN _
  3857.          ZOutTxt$ = "Sorry, Daily download limit of" + _
  3858.               STR$(ZRatioRestrict#) + " " + _
  3859.               Method$ + " Reached" : _
  3860.          ZOK = ZFalse _
  3861.       ELSE ZOutTxt$ = "Download balance remaining:" + _
  3862.                 STR$(Today#) + _
  3863.                 " " + _
  3864.                 Method$ : _
  3865.            ZOK = ZTrue
  3866.       ZSubParm = 5
  3867.       CALL TPut
  3868.       CALL SkipLine(1)
  3869.       EXIT SUB
  3870. '
  3871. 20105 IF Ratio# > ZRatioRestrict# OR ULWork# = 0 THEN _
  3872.          ZOK = ZFalse : _
  3873.          ZOutTxt$ = "Sorry, DL/UL ratio of" + _
  3874.               STR$(ZRatioRestrict#) + _
  3875.               ":1 " + _
  3876.               Method$ + " exceeded" : _
  3877.          ZSubParm = 5 : _
  3878.          CALL TPut : _
  3879.          ZOutTxt$ = "Minimum upload of" + _
  3880.               STR$(INT(((DLWork# - (ULWork# * ZRatioRestrict#)) _
  3881.               / ZRatioRestrict#) + 1)) + _
  3882.               + " " + Method$ + " required to download" _
  3883.       ELSE ZOutTxt$ = "Balance remaining before upload required:" + _
  3884.                 STR$(INT((ULWork# * ZRatioRestrict#)-DLWork#)) + _
  3885.                 " " + Method$
  3886.       ZSubParm = 5
  3887.       CALL TPut
  3888.       CALL SkipLine (1)
  3889. 20110 END SUB
  3890. 20140 ' $SUBTITLE: 'GetArc - sub to get what files to verbose list'
  3891. ' $PAGE
  3892. '
  3893. '  NAME    -- GetArc
  3894. '
  3895. '  INPUTS  --     PARAMETER                    MEANING
  3896. '                 ZWasQ                       NUMBER OF ENTRIES TYPED
  3897. '                 ZUserIn$()                  ENTRIES TYPED
  3898. '
  3899. '  OUTPUTS --
  3900. '
  3901. '  PURPOSE --  Process the V)erbose list command.
  3902. '              Takes what user types and tries to list it.
  3903. '
  3904.       SUB GetArc STATIC
  3905. 20141 IF ZAnsIndex >= ZLastIndex THEN _
  3906.          CALL QuickTPut1 ("Default extension is "+ZDefaultExtension$)
  3907.       ZOutTxt$ = "What compressed file(s)" + ZPressEnterExpert$
  3908.       CALL PopCmdStack
  3909.       IF ZSubParm = -1 OR ZWasQ = 0 THEN _
  3910.          EXIT SUB
  3911. 20142 ZViolation$ = "View ARC"
  3912.       WasX = ZAnsIndex
  3913.       FOR ZAnsIndex = WasX TO ZLastIndex
  3914.          GOSUB 20143
  3915.          IF ZSubParm < 0 THEN _
  3916.             ZAnsIndex = ZLastIndex + 1
  3917.       NEXT
  3918.       IF ZLastIndex > 1 THEN _
  3919.          EXIT SUB _
  3920.       ELSE GOTO 20141
  3921. 20143 ZWasZ$ = ZUserIn$(ZAnsIndex)
  3922.       CALL AllCaps (ZWasZ$)
  3923.       CALL BreakFileName (ZWasZ$,Drive$,Prefix$,Ext$,ZFalse)
  3924.       IF Ext$ = "" THEN _
  3925.          Ext$ = ZDefaultExtension$ : _
  3926.          ZWasZ$ = ZWasZ$ + "." + ZDefaultExtension$
  3927.       ZFileNameHold$ = ZWasZ$
  3928.       ZFileName$ = ZWasZ$
  3929.       CALL BadFile (Prefix$,BadFileNameIndex)
  3930.       ON BadFileNameIndex GOTO 20144,20146,20147
  3931. 20144 CALL BadFile (ZFileName$,BadFileNameIndex)
  3932.       ON BadFileNameIndex GOTO 20145,20146,20147
  3933. 20145 CALL RotorsDir (ZFileName$,ZSubDir$(),ZSubDirCount + (NOT ZSysop),ZTrue)
  3934.       IF ZOK THEN _
  3935.          GOTO 20148
  3936. 20146 ZWasZ$ = ZUserIn$(ZAnsIndex) + _
  3937.            " not found!"
  3938.       CALL UpdtCalr (ZWasZ$,2)
  3939.       ZOutTxt$ = ZWasZ$ + _
  3940.            " Type correct filename" + ZPressEnterExpert$
  3941.       ZSubParm = 1
  3942.       CALL TGet
  3943.       IF ZSubParm = -1 OR ZWasQ = 0 THEN _
  3944.          RETURN
  3945.       ZUserIn$(ZAnsIndex) = ZUserIn$(1)
  3946.       GOTO 20143
  3947. 20147 CALL SecViolation
  3948.       IF ZDenyAccess THEN _
  3949.          EXIT SUB
  3950.       GOTO 20146
  3951. 20148 WasX$ = ZDiskForDos$ + "V" + Ext$ + ".BAT"
  3952.       CALL FindIt (WasX$)
  3953.       IF NOT ZOK THEN _
  3954.          GOTO 20150
  3955.       ZGSRAra$(3) = MID$(RIGHT$(ZComPort$,1)+"0",1-ZLocalUser, 1)
  3956.       CALL ReadDir (2,1)
  3957.       IF EOF(2) THEN _
  3958.          ZWasZ$ = ZOutTxt$ : _
  3959.          ZGSRAra$(1) = ZFileName$ : _
  3960.          ZGSRAra$(2) = ZArcWork$ _
  3961.       ELSE ZWasZ$ = WasX$ + " " + ZFileName$ + _
  3962.                 " " + ZArcWork$ + " " + ZGSRAra$(3)
  3963.       CALL ShellExit (ZWasZ$)
  3964.       CALL BufFile (ZArcWork$,WasX)
  3965.       RETURN
  3966. 20150 WasX = INSTR(".ARC.PAK.ZIP.LZH.","."+Ext$+".")
  3967.       'IF (WasX < 1) OR (WasX = 1 AND NOT ZTurboRBBS) THEN _
  3968.       IF (WasX < 1) THEN _
  3969.          CALL QuickTPut1 ("View for "+Ext$+" not implemented") : _
  3970.          RETURN
  3971.       CALL QuickTPut1 (ZFileNameHold$ + " has these files")
  3972.       CALL ViewArc
  3973.       RETURN
  3974.       END SUB
  3975. 20235 ' $SUBTITLE: 'BadName - subroutine to find bad file names'
  3976. ' $PAGE
  3977. '
  3978. '  NAME    -- BadName
  3979. '
  3980. '  INPUTS  --     PARAMETER                    MEANING
  3981. '               ZActiveMessageFile$
  3982. '               ZActiveUserFile$
  3983. '               ZCallersFile$
  3984. '               ZCmntsFile$
  3985. '               CONFIG.FILEANAME$
  3986. '               ZMainMsgBackup$
  3987. '               ZMainMsgFile$
  3988. '               ZMaxViolations
  3989. '               ZPswdFile$
  3990. '               ZRBBSBat$
  3991. '               ZRCTTYBat$
  3992. '               ZSubDir$()
  3993. '               ZSubDirIndex
  3994. '               ZViolation$
  3995. '               ZViolationsThisSession
  3996. '               ZWasZ$                          NAME OF FILE
  3997. '
  3998. '  OUTPUTS  -- BadFileNameIndex         1 = FILE NAME IS OK
  3999. '                                       2 = SECURITY BREACH TRIED
  4000. '              ZViolationsThisSession     NUMBER OF VIOLATIONS
  4001. '              FileSpec$                   NAME OF FILE
  4002. '
  4003. '  PURPOSE -- To protect RBBS-PC against the use of bad file names
  4004. '             to either crash the system or to breach RBBS-PC's security
  4005. '
  4006.       SUB BadName (BadFileNameIndex) STATIC
  4007. '
  4008. '
  4009. ' *  TEST FOR SYSTEM FILE ATTEMPT
  4010. '
  4011.       BadFileNameIndex = 2
  4012.       ZWasZ$ = ZFileName$
  4013.       CALL BreakFileName (ZFileName$,DR$,Prefix$,Extension$,ZFalse)
  4014.       IF LEN(Extension$) = 3 THEN _
  4015.          IF INSTR("DEF,MNU,OLD,PUI,BAK,",Extension$+",") > 0 THEN _
  4016.             EXIT SUB
  4017.       ZOK = 0
  4018.       CALL FileNameCheck (ZActiveMessageFile$,Prefix$,Extension$)
  4019.       CALL FileNameCheck (ZActiveUserFile$,Prefix$,Extension$)
  4020.       CALL FileNameCheck (ZCallersFile$,Prefix$,Extension$)
  4021.       CALL FileNameCheck (ZCmntsFile$,Prefix$,Extension$)
  4022.       CALL FileNameCheck (ZFileSecFile$,Prefix$,Extension$)
  4023.       CALL FileNameCheck (ZMainMsgBackup$,Prefix$,Extension$)
  4024.       CALL FileNameCheck (ZOrigMsgFile$,Prefix$,Extension$)
  4025.       CALL FileNameCheck (ZOrigUserFile$,Prefix$,Extension$)
  4026.       CALL FileNameCheck (ZPswdFile$,Prefix$,Extension$)
  4027.       CALL FileNameCheck (ZRBBSBat$,Prefix$,Extension$)
  4028.       CALL FileNameCheck (ZRCTTYBat$,Prefix$,Extension$)
  4029.       CALL FileNameCheck (ZConfigFileName$,Prefix$,Extension$)
  4030.       IF ZOK > 0 THEN _
  4031.          EXIT SUB
  4032.       BadFileNameIndex = 1
  4033.       END SUB
  4034. 20240 ' $SUBTITLE: 'FileNameCheck - checks file match except for drive'
  4035. ' $PAGE
  4036. '
  4037. '  NAME    -- FileNameCheck
  4038. '
  4039. '  INPUTS  --     PARAMETER                    MEANING
  4040. '               CheckThis$           Name of file to check
  4041. '               Pref2$               Prefix to match against
  4042. '               Ext2$                Extension to match against
  4043. '
  4044. '  OUTPUTS  -- ZOK                    1 if got match
  4045. '
  4046. '  PURPOSE -- Checks for match on both prefix and extension of a file
  4047. '             name.   Used to catch match on system files not to be
  4048. '             downloaded.
  4049. '
  4050.       SUB FileNameCheck (CheckThis$,Pref2$,Ext2$) STATIC
  4051.       IF ZOK > 0 THEN _
  4052.          EXIT SUB
  4053.       CALL BreakFileName (CheckThis$,DR$,Pref1$,Ext1$,ZFalse)
  4054.       IF Pref1$ = Pref2$ THEN _
  4055.          IF Ext1$ = Ext2$ THEN _
  4056.             ZOK = 1
  4057.       END SUB
  4058.  
  4059.